使用条件变量同步三个线程 [英] Synchronizing three threads with Condition Variable

查看:226
本文介绍了使用条件变量同步三个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have three threads in my application, the first thread needs to wait for a data to be ready from the two other threads. The two threads are preparing the data concurrently. In order to do that I am using condition variable in C++ as following:

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();

线程3:

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

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

So my question is it correct to do that, or is there any more efficient way? I am looking for the most optimized way to do the waiting.

推荐答案

您似乎在这里需要一个信号灯,因此可以等待两个资源"被占用".

It looks like you want a semaphore here, so you can wait for two "resources" to be "taken".

现在,只用原子替换互斥.您仍然可以使用简历向服务员发信号:

For now, just replace the mutual exclusion with an atomic. you can still use a cv to signal the waiter:

#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并不重要.但是,线程检查器会(正确地)对此抱怨(我认为),因为除非添加锁定,否则它们无法检查正确的同步.
  • warning - it's essential that you know only the waiter is waiting on the cv, otherwise you need notify_all() instead of notify_one().
  • It is not important that the waiter is already waiting before the workers signal their completion, because the predicated timed_wait checks the predicate before blocking.
  • Because this sample uses atomics and predicated wait, it's not actually critical to signal the cv under the mutex. However, thread checkers will (rightly) complain about this (I think) because it's impossible for them to check proper synchronization unless you add the locking.

这篇关于使用条件变量同步三个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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