我没有看到这个程序有任何实际用法,但在尝试使用c ++ 11并发和conditional_variables时,我偶然发现了一些我并不完全理解的内容。
起初我假设使用notify_one()
将允许下面的程序工作。然而,实际上程序在打印之后就冻结了。当我切换到使用notify_all()
时,程序完成了我想要它做的事情(按顺序打印所有自然数字)。我相信这个问题已经以各种形式提出。但我的具体问题是我在doc读错的地方。
我认为notify_one()
应该有效,因为以下陈述。
如果有任何线程正在等待* this,则调用notify_one将解锁其中一个等待线程。
在下面看,只有一个线程会在给定时间被阻止,对吗?
class natural_number_printer
{
public:
void run()
{
m_odd_thread = std::thread(
std::bind(&natural_number_printer::print_odd_natural_numbers, this));
m_even_thread = std::thread(
std::bind(&natural_number_printer::print_even_natural_numbers, this));
m_odd_thread.join();
m_even_thread.join();
}
private:
std::mutex m_mutex;
std::condition_variable m_condition;
std::thread m_even_thread;
std::thread m_odd_thread;
private:
void print_odd_natural_numbers()
{
for (unsigned int i = 1; i < 100; ++i) {
if (i % 2 == 1) {
std::cout << i << " ";
m_condition.notify_all();
} else {
std::unique_lock<std::mutex> lock(m_mutex);
m_condition.wait(lock);
}
}
}
void print_even_natural_numbers()
{
for (unsigned int i = 1; i < 100; ++i) {
if (i % 2 == 0) {
std::cout << i << " ";
m_condition.notify_all();
} else {
std::unique_lock<std::mutex> lock(m_mutex);
m_condition.wait(lock);
}
}
}
};
答案 0 :(得分:2)
提供的代码“正常”工作并被设计卡住。原因在documentation
中描述notify_one()/ notify_all()和的效果 wait()/ wait_for()/ wait_until()在一个总订单中发生,所以 例如,notify_one()不可能被延迟 取消阻止在调用之后开始等待的线程 notify_one()已经完成。
分步逻辑是
print_odd_natural_numbers
线程已启动print_even_natural_numbers
线程也已启动。m_condition.notify_all();
print_even_natural_numbers
行之前执行print_odd_natural_numbers
线程到m_condition.wait(lock);
行。m_condition.wait(lock);
print_odd_natural_numbers
行,线程卡住。m_condition.wait(lock);
的{{1}}行,线程也被卡住了。