mercredi 1 juillet 2015

How to make sure all slave threads are waited for conditional variable?

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.

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://ift.tt/1dxyAvU

  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;
}

Aucun commentaire:

Enregistrer un commentaire