如何确保所有从属线程都等待条件变量?

时间:2015-07-01 14:51:04

标签: c++ multithreading c++11 boost-thread

我正在运行以下代码块。这段代码将创建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;
}

1 个答案:

答案 0 :(得分:4)

你有竞争条件 - 设置标志和通知从属线程不是原子的。因此,您必须在修改主线程中的data_ready_mutex标志之前锁定data_ready。这将消除竞争条件,从属线程将看到data_ready false并继续等待条件变量并将被通知,或者仅在data_ready设置为true后才会获取互斥锁所以它不会等待。