Java 中的“同步”对应什么功能?

问题描述 投票:0回答:5
Java中的

synchronized
可以保证访问共享对象时的线程安全。 那么 C++ 呢?

java c++ multithreading synchronization
5个回答
52
投票

在 C++ 中使用以下内容:

#include <mutex>

std::mutex _mutex;

void f()
{
     std::unique_lock<std::mutex> lock(_mutex);
     // access your resource here.
}

10
投票

尽管这个问题已经得到解答,但根据this文章的想法,我仅使用标准库(C ++ 11)对象制作了我的

synchronized
关键字版本:

#include <mutex>
#define synchronized(m) \
    for(std::unique_lock<std::recursive_mutex> lk(m); lk; lk.unlock())

您可以像这样测试它:

#include <iostream>
#include <iomanip>
#include <mutex>
#include <thread>
#include <vector>

#define synchronized(m) \
    for(std::unique_lock<std::recursive_mutex> lk(m); lk; lk.unlock())

class Test {
    std::recursive_mutex m_mutex;
public:
    void sayHello(int n) {
        synchronized(m_mutex) {
            std::cout << "Hello! My number is: ";
            std::cout << std::setw(2) << n << std::endl;
        }
    }    
};

int main() {
    Test test;
    std::vector<std::thread> threads;
    std::cout << "Test started..." << std::endl;

    for(int i = 0; i < 10; ++i)
        threads.push_back(std::thread([i, &test]() {
            for(int j = 0; j < 10; ++j) {
                test.sayHello((i * 10) + j);
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        }));    
    for(auto& t : threads) t.join(); 

    std::cout << "Test finished!" << std::endl;
    return 0;
}

这只是 Java 的

synchonized
关键字的近似值,但它是有效的。如果没有它,上一个示例的
sayHello
方法可以实现为 接受的答案 说:

void sayHello(unsigned int n) {
    std::unique_lock<std::recursive_mutex> lk(m_mutex);

    std::cout << "Hello! My number is: ";
    std::cout << std::setw(2) << n << std::endl;
}

6
投票

C++03 中没有相当于 Java 中的

synchronized
的关键字。但是可以使用Mutex来保证线程的安全。


2
投票

C++ 还没有内置线程或同步,您必须为此使用库。

Boost.Thread
是一个很好的可移植库,旨在与 C++0x 中建议的线程设施兼容。


0
投票
为了非常干净的使用语法,我定义了这个宏:

// Under the hood, we use a mutex to synchronize. #include <mutex> // Create a synchronized keyword. #define CONCAT_INNER(a, b) a##b #define CONCAT(a, b) CONCAT_INNER(a, b) #define UNIQUE_NAME(base) CONCAT(base, __LINE__) #define synchronized static std::mutex UNIQUE_NAME(syncMutex); std::unique_lock<std::mutex> syncLock(UNIQUE_NAME(syncMutex))
这对我来说适用于所有三种流行的编译器{Windows、Clang、GCC}。该宏为该函数创建一个唯一的静态互斥变量,并立即将其锁定在该函数的范围内。它也可以在任何范围内使用,而不仅仅是函数范围。

要在函数中使用它,只需执行以下操作:

// Define a function we want to synchronize. void synchronizedFunction() { // Synchronize this function. synchronized; // We are now synchronized. }
您可以尝试这个测试程序来证明它有效:

// Under the hood, we use a mutex to synchronize. #include <mutex> // Create a synchronized keyword. #define CONCAT_INNER(a, b) a##b #define CONCAT(a, b) CONCAT_INNER(a, b) #define UNIQUE_NAME(base) CONCAT(base, __LINE__) #define synchronized static std::mutex UNIQUE_NAME(syncMutex); std::unique_lock<std::mutex> syncLock(UNIQUE_NAME(syncMutex)) // For our test program below. #include <iostream> #include <thread> // Define a function we want to synchronize. void synchronizedFunction() { // Synchronize this function. synchronized; // Print something, then sleep for 1 second, then print something else. // If we're synchronized, these two messages will appear back-to-back. // If we're not synchronized, these messages display in an uncontrolled fashion. std::cout << "Thread " << std::this_thread::get_id() << " is entering." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "Thread " << std::this_thread::get_id() << " is exiting." << std::endl; } // A simple test program that will access our synchronized function from 2 asynchronous threads. int main() { // Construct a new thread and have it call our synchronized function. std::thread newThread(synchronizedFunction); // In our main thread, also call our synchronized function. synchronizedFunction(); // Join both threads before exiting. newThread.join(); // Exit. return 0; }
当您运行此程序时,您将获得以下输出 - 演示对每个访问线程的函数的访问都是序列化的。您会注意到从进入函数到退出函数(两次)都有一秒的延迟。由于该函数现已序列化,因此测试程序大约需要 2 秒才能完成该函数:

Thread 140737353824064 is entering. Thread 140737353824064 is exiting. Thread 140737257031424 is entering. Thread 140737257031424 is exiting.
如果注释掉“synchronized;”语句,那么您将看到两个线程同时进入该函数,产生类似于以下输出的内容,或者您可能会看到文本踩在其自身之上。因为我们不再同步,所以测试程序大约需要 1 秒才能完成,而不是 2 秒:

Thread 140737257031424 is entering. Thread 140737353824064 is entering. Thread 140737257031424 is exiting. Thread 140737353824064 is exiting.
    
© www.soinside.com 2019 - 2024. All rights reserved.