为什么在我们已经有一个通知变量时使用 condition_variable?
why use condition_variable when we already have a notifying variable?
考虑以下代码:
int main() {
bool done = false;
condition_variable con;
mutex m;
thread producer([&]() {
this_thread::sleep_for(chrono::seconds(10));
done = true;
//con.notify_one();
});
thread consumer([&]() {
/*unique_lock<mutex> lock(m);
while (!done) {
con.wait(lock);
}*/
while (!done);
cout << "now my turn..."<<endl;
});
producer.join();
consumer.join();
}
如果我取消注释 2 个线程中的代码,我将使用 condition_variable。所以消费者线程看起来像这样:
thread consumer([&]() {
unique_lock<mutex> lock(m);
while (!done) {
con.wait(lock);
}
// while (!done); <-this is equivalent of the above
cout << "now my turn..."<<endl;
});
看来我也能达到同样的效果with/withoutcondition_variable。
所以我的问题是:如果已经使用了通知变量(在本例中为 'done' 变量),为什么我们需要 condition_variable?使用它有什么好处?我可以做一些通知变量不能做的事情吗?
当等待条件变量时,线程被阻塞(即不执行)。收到通知后,线程将进入就绪状态,因此 OS 可以对其进行调度。
这比线程 "busy-waiting" 更有效,后者不断轮询变量以检查它是否可以继续。在那种情况下,线程用完了 CPU 个可用于实际工作的周期。
您还需要使用条件变量来正确保护临界区不被多个线程同时访问。你可能有 3 个消费者 运行 但一次只允许一个人工作(其他人可能在那之前做其他事情)。
考虑以下代码:
int main() {
bool done = false;
condition_variable con;
mutex m;
thread producer([&]() {
this_thread::sleep_for(chrono::seconds(10));
done = true;
//con.notify_one();
});
thread consumer([&]() {
/*unique_lock<mutex> lock(m);
while (!done) {
con.wait(lock);
}*/
while (!done);
cout << "now my turn..."<<endl;
});
producer.join();
consumer.join();
}
如果我取消注释 2 个线程中的代码,我将使用 condition_variable。所以消费者线程看起来像这样:
thread consumer([&]() {
unique_lock<mutex> lock(m);
while (!done) {
con.wait(lock);
}
// while (!done); <-this is equivalent of the above
cout << "now my turn..."<<endl;
});
看来我也能达到同样的效果with/withoutcondition_variable。 所以我的问题是:如果已经使用了通知变量(在本例中为 'done' 变量),为什么我们需要 condition_variable?使用它有什么好处?我可以做一些通知变量不能做的事情吗?
当等待条件变量时,线程被阻塞(即不执行)。收到通知后,线程将进入就绪状态,因此 OS 可以对其进行调度。
这比线程 "busy-waiting" 更有效,后者不断轮询变量以检查它是否可以继续。在那种情况下,线程用完了 CPU 个可用于实际工作的周期。
您还需要使用条件变量来正确保护临界区不被多个线程同时访问。你可能有 3 个消费者 运行 但一次只允许一个人工作(其他人可能在那之前做其他事情)。