【发布时间】:2015-12-22 05:47:17
【问题描述】:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
std::mutex globalMutex;
std::condition_variable globalCondition;
int global = 0;
int activity = 0;
int CountOfThread = 1; // or more than 1
// just for console display, not effect the problem
std::mutex consoleMutex;
void producer() {
while (true) {
{
std::unique_lock<std::mutex> lock(globalMutex);
while (activity == 0) {
lock.unlock();
std::this_thread::yield();
lock.lock();
}
global++;
globalCondition.notify_one();
}
std::this_thread::yield();
}
}
void customer() {
while (true) {
int x;
{
std::unique_lock<std::mutex> lock(globalMutex);
activity++;
globalCondition.wait(lock); // <- problem
activity--;
x = global;
}
{
std::lock_guard<std::mutex> lock(consoleMutex);
std::cout << x << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 0; i < CountOfThread; ++i) {
std::thread(customer).detach();
}
std::thread(producer).detach();
getchar();
return 0;
}
我想要的是确保每次有客户线程来获得增加的全局,期望显示如下:1、2、3,...,但我看到的是全局值将在等待和之间增加活动——因此,实际显示为:1、23、56、78、....
我发现问题出在wait()中,在wait()中有3个步骤,'unlock,wait,lock',在signaled(wait return)和mutex.lock之间,不是原子操作,生产者线程可能会在wait()之前加锁mutex 锁mutex,并且activity仍然不为零,所以全局会增加,意外
有没有办法确定我的期望?
【问题讨论】:
-
恭喜您发布了一个完整的最小示例。它有很大帮助!
标签: c++ multithreading producer-consumer condition-variable