如何确保所有从属线程都等待条件变量?
How to make sure all slave threads are waited for conditional variable?
我运行正在编写以下代码块。此代码将创建 5 个从属线程和 1 个主线程。所有从线程等待主线程准备好数据,当数据准备好后,所有从线程将通知开始处理。
我的问题是,有可能在从线程开始等待conditional_variable
之前,主线程准备好数据并通知等待的线程。在这种情况下,一些等待的线程将收到通知并开始处理,但未等待的线程将开始等待永远不会到来的通知。
如果你运行这个例子,这种情况不会发生,但我正在寻找一种方法来确保所有从属线程都在等待通知,然后通知它们。你知道我该怎么做吗?
/*
Condition Variables - Many waiting threads
Shows how one condition variable can be used to notify multiple threads
that a condition has occured.
* Part of "Threading with Boost - Part IV: Condition Variables", published at:
http://antonym.org/boost
Copyright (c) 2015 Gavin Baker <gavinb@antonym.org>
Published under the MIT license, see LICENSE for details
*/
#include <cstdio>
#include <boost/thread.hpp>
boost::condition_variable data_ready_cond;
boost::mutex data_ready_mutex;
bool data_ready = false;
void master_thread()
{
printf("+++ master thread\n");
// Pretend to work
printf(" master sleeping...\n");
boost::chrono::milliseconds sleepDuration(750);
boost::this_thread::sleep_for(sleepDuration);
// Let other threads know we're done
printf(" master notifying...\n");
data_ready = true;
data_ready_cond.notify_all();
printf("--- master thread\n");
}
void slave_thread(int id)
{
printf("+++ slave thread: %d\n", id);
boost::unique_lock<boost::mutex> lock(data_ready_mutex);
while (!data_ready)
{
data_ready_cond.wait(lock);
}
printf("--- slave thread: %d\n", id);
}
int main()
{
printf("Spawning threads...\n");
boost::thread slave_1(slave_thread, 1);
boost::thread slave_2(slave_thread, 2);
boost::thread slave_3(slave_thread, 3);
boost::thread slave_4(slave_thread, 4);
boost::thread master(master_thread);
printf("Waiting for threads to complete...\n");
slave_1.join();
slave_2.join();
slave_3.join();
slave_4.join();
master.join();
printf("Done\n");
return 0;
}
您有竞争条件 - 设置标志和通知从属线程不是原子的。所以你只需要在修改主线程中的 data_ready
标志之前锁定 data_ready_mutex
。这将消除竞争条件,从属线程要么会看到 data_ready
false 并等待条件变量并收到通知,要么仅在 data_ready
设置为 true
后才获取互斥锁所以它根本不会等待。
我运行正在编写以下代码块。此代码将创建 5 个从属线程和 1 个主线程。所有从线程等待主线程准备好数据,当数据准备好后,所有从线程将通知开始处理。
我的问题是,有可能在从线程开始等待conditional_variable
之前,主线程准备好数据并通知等待的线程。在这种情况下,一些等待的线程将收到通知并开始处理,但未等待的线程将开始等待永远不会到来的通知。
如果你运行这个例子,这种情况不会发生,但我正在寻找一种方法来确保所有从属线程都在等待通知,然后通知它们。你知道我该怎么做吗?
/*
Condition Variables - Many waiting threads
Shows how one condition variable can be used to notify multiple threads
that a condition has occured.
* Part of "Threading with Boost - Part IV: Condition Variables", published at:
http://antonym.org/boost
Copyright (c) 2015 Gavin Baker <gavinb@antonym.org>
Published under the MIT license, see LICENSE for details
*/
#include <cstdio>
#include <boost/thread.hpp>
boost::condition_variable data_ready_cond;
boost::mutex data_ready_mutex;
bool data_ready = false;
void master_thread()
{
printf("+++ master thread\n");
// Pretend to work
printf(" master sleeping...\n");
boost::chrono::milliseconds sleepDuration(750);
boost::this_thread::sleep_for(sleepDuration);
// Let other threads know we're done
printf(" master notifying...\n");
data_ready = true;
data_ready_cond.notify_all();
printf("--- master thread\n");
}
void slave_thread(int id)
{
printf("+++ slave thread: %d\n", id);
boost::unique_lock<boost::mutex> lock(data_ready_mutex);
while (!data_ready)
{
data_ready_cond.wait(lock);
}
printf("--- slave thread: %d\n", id);
}
int main()
{
printf("Spawning threads...\n");
boost::thread slave_1(slave_thread, 1);
boost::thread slave_2(slave_thread, 2);
boost::thread slave_3(slave_thread, 3);
boost::thread slave_4(slave_thread, 4);
boost::thread master(master_thread);
printf("Waiting for threads to complete...\n");
slave_1.join();
slave_2.join();
slave_3.join();
slave_4.join();
master.join();
printf("Done\n");
return 0;
}
您有竞争条件 - 设置标志和通知从属线程不是原子的。所以你只需要在修改主线程中的 data_ready
标志之前锁定 data_ready_mutex
。这将消除竞争条件,从属线程要么会看到 data_ready
false 并等待条件变量并收到通知,要么仅在 data_ready
设置为 true
后才获取互斥锁所以它根本不会等待。