繁体   English   中英

条件变量 - 等待/通知竞争条件

[英]Condition Variable - Wait/Notify Race Condition

我将首先介绍一些代码,因为解释更容易。 假设互斥锁正确地与条件变量一起使用以保持简单:

// Thread 1
while(1)
{
    conditionVariable.wait();
    // Do some work
}

// Thread 2
while(1)
{
    // Do some work
    conditionVariable.notify_one();
}

// Thread 3
while(1)
{
    // Do some work
    conditionVariable.notify_one();
}

我想要实现的是线程1保证在线程2或线程3通知时等待条件变量。 正如代码所代表的那样, notify_one()wait()之间存在很大的差距,其形式是由注释标记的其他代码。 这个差距意味着有时在调用wait()之前调用notify_one() wait()

经过一番思考后,似乎最接近我的是在notify_one()之前和wait()之前(在线程1的循环开始时wait()使用某种形式的互斥。 但是,无论如何完成,在互斥和wait()之间仍然存在一个小的间隙(1行代码wait() ,允许线程2和3在线程1调用wait()之前调用notify_one() wait() 这不太可能,但可能。

我还考虑过使用wait()谓词来标记一个允许其他线程通知的布尔值。 我想这可行,因为wait()是原子的,但我想知道是否有更好的方法。 也许我接近这个错误。

总结:在允许线程2和3通知之前,如何确保线程1正在等待?

简而言之:将条件变量视为一种方法,通知其他线程某些事情发生了变化,而不仅仅是作为信号。

为了做到这一点,条件变量应该伴随一个条件(简单的例子:一个整数递增),可以由接收线程处理。

现在,为了解决您的问题,线程1可以使用带有ready布尔值的条件变量来在其准备接收条件变量信号时发信号通知其他线程,但是您最好先检查原始条件变量是否可以按照描述使用这里。

基于问题的伪代码(仍然需要正确锁定conditionVariable):

// Thread 1
while(1)
{
    lockReady();
    ready = true;
    unlockReady();
    readyCV.notify_one();
    conditionVariable.wait();

    // Do some work
}

// Thread 2
while(1)
{
    lockReady();
    while (! ready) readyCV.wait();
    ready = false;
    unlockReady();
    // Do some work
    conditionVariable.notify_one();
}

// Thread 3
while(1)
{
    lockReady();
    while (! ready) readyCV.wait();
    ready = false;
    unlockReady();
    // Do some work
    conditionVariable.notify_one();
}

另见我之前的回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM