如果条件变量发出信号到锁定的线程怎么办?

xiv*_*r77 3 c multithreading mutex pthreads condition-variable

在下面的(伪)代码中,cond无论出于何种原因,它可能会在不应该唤醒的情况下唤醒.所以我在那里放了一个while循环.当它确实唤醒时,它仍将消耗锁定,因此可以保证out()只有一个线程正在执行其工作.

但是,如果虽然有一个虚假的唤醒out(),同时in()发出信号out(),但是在那个时刻out()由于虚假的唤醒已经被锁定,会发生什么.那么如果cond向锁定线程发出信号会发生什么?

in()
    inLock.lock()
    isEmpty = false
    cond.signal()
    inLock.unlock()

out()
    outLock.lock()
    while isEmpty
        cond.wait(outLock)
    isEmpty = true
    outLock.unlock()
Run Code Online (Sandbox Code Playgroud)


注意

那么,是100%的安全,我知道我可以使用一个互斥两个in()out(),但我使用的数据结构是100%安全的,当输入和输出发生在同一时间; 它是一种队列.而且我认为在填充一些新数据时阻止从队列读出的任何内容都是一种性能折衷,反之亦然.

我确实考虑过使用信号量,但问题是,无论出于何种原因,许多C和C++库都没有实现信号量.

caf*_*caf 5

in()线程设置isEmpty = falseout()线程测试时,您必须使用相同的互斥锁while (isEmpty).否则,这可能发生:

  1. out()线程测试isEmpty,发现它是真的;
  2. in()线程设置isEmpty为false并发出条件变量的信号(但是没有人醒来,因为没有人在等待);
  3. out()cond.wait()尽管队列不再是空的,但线程调用和永久阻塞.

请注意,在这个序列中没有一个虚假的唤醒 - 它只是一个普通的老竞争条件.

只要您isEmpty使用与测试时相同的互斥锁进行更新,isEmpty就不会发生此交错.