c++ - 如何正确使用 std::condition_variable?

标签 c++ multithreading concurrency condition-variable

我对 conditions_variables 以及如何(安全地)使用它们感到困惑。在我的应用程序中,我有一个生成 gui 线程的类,但是当 gui 由 gui 线程构建时,主线程需要等待。

情况与下面的函数相同。主线程生成互斥锁、锁和condition_variable。然后它制作线程。虽然这个 worker thread 还没有通过某个点(这里打印数字),主线程不允许继续(即必须 wait 用于打印所有数字)。

如何在此上下文中正确使用 condition_variables?另外,我读到自发唤醒是一个问题。我该如何处理它们?

    int main()
    {
        std::mutex mtx;
        std::unique_lock<std::mutex> lck(mtx);
        std::condition_variable convar;

        auto worker = std::thread([&]{
            /* Do some work. Main-thread can not continue. */
            for(int i=0; i<100; ++i) std::cout<<i<<" ";
            convar.notify_all(); // let main thread continue
            std::cout<<"\nworker done"<<std::endl;       
        });


        // The main thread can do some work but then must wait until the worker has done it's calculations.
        /* do some stuff */
        convar.wait(lck);
        std::cout<<"\nmain can continue"<<std::endl; // allowed before worker is entirely finished
        worker.join();
    }

最佳答案

通常,您会有一些可观察到的共享状态,您会阻止其更改:

bool done = false;
std::mutex done_mx;
std::condition_variable done_cv;

{
  std::unique_lock<std::mutex> lock(done_mx);

  std::thread worker([&]() {
    // ...
    std::lock_guard<std::mutex> lock(done_mx);
    done = true;
    done_cv.notify_one();
  });

  while (true) { done_cv.wait(lock); if (done) break; }

  // ready, do other work

  worker.join();
}

请注意,您在循环中等待,直到满足实际条件。另请注意,对实际共享状态 ( done ) 的访问是通过互斥锁 done_mx 序列化的。 , 每当 done 时被锁定被访问。

有一个辅助成员函数可以为您执行条件检查,因此您不需要循环:

done_cv.wait(lock, [&]() { return done; });

关于c++ - 如何正确使用 std::condition_variable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43898137/

相关文章:

go - 等待并发 worker 完成后退出

hadoop - 并发执行 “single-threaded” hadoop:瓶颈在哪里?

c++ - 如何创建 ELF 可执行文件?

java vs C++ 通过引用传递

java - 如何在两个线程之间共享变量

c# - 多处理器系统中 volatile 关键字的成本是多少?

java - Java程序中的事件延迟

c++ - '...' token 之前的预期类型说明符

Android 手机的 Java 编译器

python - pycurl/curl 不遵循 CURLOPT_TIMEOUT 选项