#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, ....C++: condition-variable wait
Я выяснил, что проблема в ожидании(), acutully there 3 этапа ожидания(), «разблокировка, ожидание, блокировка», между сигналами (wait return) и mutex.lock, это не атомная операция, поток производителя может блокировать mutex перед wait() для блокировки мьютекса, а активность по-прежнему не равна нулю, поэтому глобальное увеличение будет неожиданно
есть ли способ убедиться, что я ожидаю?
Поздравляет на размещение полного минимальный примера. Это очень помогает! –