我在C ++ 11的thread.h api方面没有广泛的知识(实际上我也不熟悉线程编程,但我最近读了很多,知道并发和类似的东西)但我开始使用它,我面临一个我还没有真正遇到过的问题。
我有两个线程函数,比如说这些
std::thread(thread1, args); // Spawn thread 1
std::thread(thread2, args); // Spawn thread 2
[...]
int thread1(bunch of args)
{
lock_thread_2();
[do stuff]
while (some condition) {
[do stuff]
unlock_thread_2();
}
}
int thread2(bunch of args)
{
while (some condition) {
[do stuff]
wait_for_thread1_to_unlock_me();
}
}
我首先考虑使用std :: mutex进行操作,但我读到它可能很危险,因为如果我解锁已经解锁的互斥锁并且在它之上它不会像mutex一样工作,那么行为是不确定的.lock()并不一定会暂停执行(只有在互斥锁已被锁定的情况下才会执行)因此写入时非常可怕,我必须将unlock()和lock锁定( )一起打电话。
这里需要注意的重要事项是thread2的执行仅由thread1控制,但thread2永远不会以任何方式锁定thread1。只有thread2被thread1锁定,只有thread1控制执行流程thread2,否则不会。
你会如何以一种干净的方式,支持的方式做到这一点?你愿意举一个代码的例子吗?
谢谢!
答案 0 :(得分:5)
std::condition_variable cv;
int thread1(bunch of args)
{
[do stuff]
while (some condition) {
[do stuff]
cv.notify_one();
}
}
int thread2(bunch of args)
{
std::mutex mtx;
std::unique_lock<std::mutex> lk(mtx);
while (some condition) {
[do stuff]
cv.wait(lk);
}
}
当wait()
返回时,cv
将被notify()
- 编辑...或者会有虚假的唤醒。为了处理后者,添加谓词通常很有帮助。
答案 1 :(得分:2)
您可以使用Array
(
[1] => Array
(
[patient] => 987
[condition] => xyz
)
)
。它允许您通过使用std::condition_variable
或notify_one
方法从另一个线程通知线程,以分别恢复等待条件变量的一个或所有线程。在您的代码中,您可以像这样使用它:
notify_all
但要注意,条件变量会偶尔出现虚假唤醒,因此您可能需要循环等待条件以检查唤醒是否有效,如下所示:
std::condition_variable my_var;
void thread1(args) {
...
while(condition1) {
...
my_var.notify_one();
}
}
void thread2(args) {
std::mutex mutex;
std::unique_lock<std::mutex> lock(mutex);
...
while(condition2) {
...
my_var.wait(lock);
}
}
您可以详细了解do {
my_var.wait(lock);
} while(!valid_wakeup);
here。