条件变量-等待/通知比赛条件 [英] Condition Variable - Wait/Notify Race Condition

查看:147
本文介绍了条件变量-等待/通知比赛条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将首先介绍一些代码,因为这样解释起来会更容易.假定条件变量正确使用了互斥锁以使其简单:

I'll present some code first since explaining is easier that way. Assume that mutexes are correctly used with the condition variables to keep it simple:

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

我想实现的是,当线程2或线程3通知时,保证线程1正在等待条件变量.从代码的角度来看,notify_one()wait()之间存在很大的差距,其形式为注释所标记的其他代码.这个间隔意味着有时notify_one()在被调用之前就被调用.

What I would like to achieve is that thread 1 is guaranteed to be waiting on the condition variable when thread 2 or Thread 3 notifies. As the code stands, there is a large gap between notify_one() and wait() in the form of some other code marked by the comments. This gap means sometimes notify_one() is called before gets a chance to call wait().

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

After some thought it seems that the closest I can get to this is to use some form of mutual exclusion before notify_one() and before wait() (at the start of thread 1's loop). However, no matter how this is done, there is still a small gap (1 line of code) between the mutual exclusion and the wait(), allowing Threads 2 and 3 to call notify_one() just before Thread 1 calls wait(). It's unlikely, but possible.

我还考虑过使用wait()谓词标记一个布尔值,以允许其他线程进行通知.我想这会起作用,因为wait()是原子的,但是我想知道是否有更好的方法.也许我处理方法不正确.

I also thought about using the wait() predicate to flag a boolean allowing the other threads to notify. I guess this would work since wait() is atomic, but I'm wondering if there is a better way. Perhaps I am approaching this incorrectly.

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

In summary: how can I ensure thread 1 is waiting before allowing threads 2 and 3 to notify?

推荐答案

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

In short: think about condition variables as a method to notify other threads that something has changed, not just as a signal.

为此,条件变量应该伴随一个可以由接收线程处理的条件(简单的示例:一个整数递增).

In order to do this, the condition variable should accompany a condition (simple example: an integer is incremented) that can be handled by the receiving thread.

现在,要解决您的问题,线程1可以在准备好接收条件变量信号时使用带有就绪布尔值的条件变量来发信号通知其他线程,但是最好先检查原始条件变量是否可以被接收.按此处所述使用.

Now, to solve your problem, thread 1 can use a condition variable accompanied by a ready boolean to signal the other threads when it is ready to receive the condition variable signal, but you better check first whether the original condition variable can be used as described here.

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

pseudo code based on question (proper locking of conditionVariable still needed):

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

另请参见我的先前的答案

这篇关于条件变量-等待/通知比赛条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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