如何正确使用std::condition_variable?
How to use a std::condition_variable correctly?
我对 conditions_variables
以及如何(安全地)使用它们感到困惑。在我的应用程序中,我有一个创建 gui 线程的 class,但是当 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; });
我对 conditions_variables
以及如何(安全地)使用它们感到困惑。在我的应用程序中,我有一个创建 gui 线程的 class,但是当 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; });