使用条件变量同步三个线程

时间:2014-04-02 11:10:12

标签: c++ multithreading boost

我的应用程序中有三个线程,第一个线程需要等待其他两个线程准备好数据。这两个线程正在同时准备数据。 为了做到这一点,我在C ++中使用条件变量如下:

boost::mutex mut;       
boost::condition_variable cond;     

线程1:

    bool check_data_received()
    {
         return (data1_received && data2_received);
    }

    // Wait until socket data has arrived
    boost::unique_lock<boost::mutex> lock(mut);
    if (!cond.timed_wait(lock, boost::posix_time::milliseconds(200),
        boost::bind(&check_data_received)))
    {

    }

线程2:

    {
        boost::lock_guard<boost::mutex> lock(mut);
        data1_received = true;
    }
    cond.notify_one();

Thread3:

    {
        boost::lock_guard<boost::mutex> lock(mut);
        data2_received = true;
    }
    cond.notify_one();

所以我的问题是这样做是正确的,还是有更有效的方法?我正在寻找最优化的等待方式。

1 个答案:

答案 0 :(得分:2)

看起来你想要一个信号量,所以你可以等待两个&#34;资源&#34;被采取&#34;。

目前,只需用原子替换互斥。你仍然可以使用简历来告知服务员:

#include <boost/thread.hpp>

boost::mutex mut;       
boost::condition_variable cond;     

boost::atomic_bool data1_received(false);
boost::atomic_bool data2_received(false);

bool check_data_received()
{
    return (data1_received && data2_received);
}

void thread1()
{
    // Wait until socket data has arrived
    boost::unique_lock<boost::mutex> lock(mut);
    while (!cond.timed_wait(lock, boost::posix_time::milliseconds(200),
        boost::bind(&check_data_received)))
    {
        std::cout << "." << std::flush;
    }
}

void thread2()
{
    boost::this_thread::sleep_for(boost::chrono::milliseconds(rand() % 4000));
    data1_received = true;
    cond.notify_one();
}

void thread3()
{
    boost::this_thread::sleep_for(boost::chrono::milliseconds(rand() % 4000));
    data2_received = true;
    cond.notify_one();
}

int main()
{
    boost::thread_group g;
    g.create_thread(thread1);
    g.create_thread(thread2);
    g.create_thread(thread3);

    g.join_all();
}

注意:

  • 警告 - 您必须知道服务员正在等待cv,否则您需要 notify_all() notify_one()
  • 在工作人员发出信号完成之前服务员已经等待 非常重要,因为谓词timed_wait会在阻止之前检查谓词。
  • 由于此示例使用原子和谓词等待,因此在互斥锁下发出cv信号实际上并不重要。但是,线程检查器会(正确地)抱怨这个(我认为),因为除非你添加锁定,否则他们无法检查正确的同步。