我沒有看到這個程序有任何實際用法,但在試驗C++ 11併發性和conditional_variables時,我偶然發現了一些我不完全瞭解的東西。C++ 11 std :: condition_variable - notify_one()行爲不如預期?
起初我假定使用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);
}
}
}
};
您有一個競爭條件 - 如果發生notify()或notify_all(),並且沒有任何條件等待,則不會釋放任何內容。如果線程在通知之後到達,那麼它將會錯過將會釋放它的通知,並且它會停留在那裏。我不確定爲什麼使用'notify_all()'時看不到問題,但有時候這就是競爭條件的本質。 –
@MichaelBurr通過什麼機制可以同步兩個線程的啓動?沒有產生僵局。 –