synchronized
在Java中可以确保访问共享对象时的线程安全性。那么C++中呢?
synchronized
在Java中可以确保访问共享对象时的线程安全性。那么C++中呢?
在C++中使用以下代码:
#include <mutex>
std::mutex _mutex;
void f()
{
std::unique_lock<std::mutex> lock(_mutex);
// access your resource here.
}
synchronized
关键字,只使用标准库(C++11)对象即可。文章链接:this。#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 中 synchronized
关键字的一个近似,但它可以工作。如果没有它,前面例子的 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;
}
C++03中没有与Java中的synchronized
等效的关键字。但是,您可以使用Mutex来确保线程的安全性。
// 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))
// 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;
}
Thread 140737353824064 is entering.
Thread 140737353824064 is exiting.
Thread 140737257031424 is entering.
Thread 140737257031424 is exiting.
Thread 140737257031424 is entering.
Thread 140737353824064 is entering.
Thread 140737257031424 is exiting.
Thread 140737353824064 is exiting.
synchronized
宏,那么又会出现未定义的行为,因为我们需要锁定同一个互斥锁。虽然代码看起来是受保护的,但实际上并非如此。 - undefined