如何确保所有从线程都等待条件变量? [英] How to make sure all slave threads are waited for conditional variable?

查看:229
本文介绍了如何确保所有从线程都等待条件变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我运行下面的代码块。这段代码将创建5个从线程和1个主线程。所有从线程都等待主线程准备好数据,当数据准备就绪时,所有从机都会通知开始处理。

I am running the following chunk of the code. This code is going to create 5 slave threads and 1 main thread. All slave threads are waited for the main thread to make the data ready and when the data gets ready, all slaves will notify to start processing.

我的问题是,可能在从线程开始等待 conditional_variable 之前,主线程使数据就绪并通知等待的线程。在这种情况下,等待的某些线程将获得通知并开始处理,但未等待的线程将开始等待将永远不会到达的通知。

My question is, it is possible that before the slave threads start waiting for the conditional_variable, the main thread make the data ready and notify the waited threads. In this case, some threads which were waited will get the notification and start processing but the ones which were not waited, will starting waiting for a notification which will NEVER come.

如果你运行这个例子,这种情况不会发生,但我正在寻找一种方法,以确保所有的从线程正在等待通知,然后通知他们。你知道我该怎么做吗?

If you run this example, this case won't happen but I am looking for a way to make sure that all the slave threads are waiting for the notification, then notifying them. Do you know how can I do that?

/*
  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并且去等待条件变量并且将被通知,或者它将仅在<$ c $之后获得互斥锁c> data_ready 设置为 true ,因此不会等待。

You have race condition - setting flag and notifying slave threads is not atomic. So you just have to lock data_ready_mutex before you are modifying data_ready flag in main thread. This will eliminate race condition, slave thread either will see data_ready false and go to wait on condition variable and will be notified, or it will acquire mutex lock only after data_ready is set to true and so it will not wait at all.

这篇关于如何确保所有从线程都等待条件变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆