在boost中等待多个条件变量?

18 c++ multithreading boost

我正在寻找一种等待多个条件变量的方法.即.就像是:

boost::condition_variable cond1;  
boost::condition_variable cond2;

void wait_for_data_to_process()  
{  
    boost::unique_lock<boost::mutex> lock(mut);

    wait_any(lock, cond1, cond2); //boost only provides cond1.wait(lock);

    process_data();
}
Run Code Online (Sandbox Code Playgroud)

条件变量可能是这样的.如果没有替代解决方案?

谢谢

Man*_*agu 12

我不相信你可以用boost :: thread做这样的事情.也许是因为POSIX条件变量不允许这种类型的构造.当然,Windows将WaitForMultipleObjects作为aJ发布,如果您愿意将代码限制为Windows同步原语,这可能是一种解决方案.

另一种选择是使用较少的条件变量:只有1个条件变量,当发生任何"有趣"时,你会触发它.然后,在你想等待的任何时候,你运行一个循环来检查你的特定兴趣情况是否已经出现,如果没有,则返回等待条件变量.你应该在这样的循环中等待那些条件变量,因为条件变量等待受到虚假的唤醒(来自boost :: thread docs,强调我的):

void wait(boost::unique_lock<boost::mutex>& lock)
...
效果:
以原子方式调用lock.unlock()并阻止当前线程.当通过this->notify_one()this->notify_all()虚假地通知时,线程将解除阻塞....

  • 在我看来,为"1或2改变"的第三个条件变量确实是最好的方法.另一种方法是使用select将wait on condition转换为等待文件描述符,并使用管道进行线程通信.由于这个问题是通用的(它没有解释等待什么东西),因此选择会更好是不明确的. (4认同)

Emi*_*ier 11

正如Managu已经回答的那样,您可以使用相同的条件变量并在while循环中检查多个"事件"(bool变量).但是,必须使用condvar使用的相同互斥锁来保护对这些bool变量的并发访问.

由于我已经遇到了为相关问题键入此代码示例的麻烦,我将在此处重新发布:

boost::condition_variable condvar;
boost::mutex mutex;
bool finished1 = false;
bool finished2 = false;

void longComputation1()
{
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished1 = false;
    }
    // Perform long computation
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished1 = true;
    }
    condvar.notify_one();
}

void longComputation2()
{
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished2 = false;
    }
    // Perform long computation
    {
        boost::lock_guard<boost::mutex> lock(mutex);
        finished2 = true;
    }
    condvar.notify_one();
}

void somefunction()
{
    // Wait for long computations to finish without "spinning"
    boost::lock_guard<boost::mutex> lock(mutex);
    while(!finished1 && !finished2)
    {
        condvar.wait(lock);
    }

    // Computations are finished
}
Run Code Online (Sandbox Code Playgroud)