C++:条件变量等待

标签 c++ multithreading producer-consumer condition-variable

#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,...,但我看到的是全局值将在等待和之间增加activity-- 因此,实际显示为:1, 23, 56, 78, ....

我发现问题在 wait() 中,实际上 wait() 中有 3 个步骤,'unlock, wait, lock',在 signaled(wait return) 和 mutex.lock 之间,这不是原子操作,producer线程可能在wait()锁mutex之前就锁了mutex,activity还是不为0,所以global会增加,出乎意料

有没有办法确定我的期望?

最佳答案

你的问题是,当 activity > 0 时,producer 可以循环获取锁、递增全局并通知条件变量。 (通知不必有相应的服务员)。

您对 thread.yield 的重复调用有点危险 - 它们意味着您正在轮询,而不是等待。我认为解决方案是您需要两个 条件变量。生产者等待一个直到被消费者通知,消费者等待另一个直到它被生产者通知。不过,我不太确定您是如何与多个消费者一起工作的。

关于C++:条件变量等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34409228/

相关文章:

ruby - 我如何使用 Celluloid 并行执行我的插件?

C++ while 循环问题

c++ - 如何在 C/C++ 程序中创建标签

multithreading - Perl Fork 线程捕获输出

java - 多生产者,单一消费者的情况

c++ - C++中的无锁多生产者多消费者

multithreading - 消费者和生产者之间的Qt线程释放? Qmutex? Q信号量?什么?

c++ - 消除 C++ 中多余的模板参数

java - 从 C++ 中诊断与 JNI 一起使用的第三方 jar 中的 SIGBUS

c# - UI 调度缓冲?