Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如果一个条件变量向一个锁定的线程发送信号怎么办?_C_Multithreading_Pthreads_Mutex_Condition Variable - Fatal编程技术网

C 如果一个条件变量向一个锁定的线程发送信号怎么办?

C 如果一个条件变量向一个锁定的线程发送信号怎么办?,c,multithreading,pthreads,mutex,condition-variable,C,Multithreading,Pthreads,Mutex,Condition Variable,在下面的(伪)代码中,cond可能会在不应该醒来的时候醒来,不管出于什么原因。所以我在那里放了一个while循环。当它确实醒来时,它仍然会使用锁,因此可以保证inout()只有一个线程在执行它的工作 但是,如果在out()中存在虚假唤醒,同时in()向out()发出信号,但此时out()由于虚假唤醒已被锁定,会发生什么情况。那么,如果cond向锁定线程发送信号,会发生什么情况呢 in() inLock.lock() isEmpty = false cond.signal(

在下面的(伪)代码中,
cond
可能会在不应该醒来的时候醒来,不管出于什么原因。所以我在那里放了一个while循环。当它确实醒来时,它仍然会使用锁,因此可以保证in
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()

注意

嗯,为了100%安全,我知道我可以对
in()
out()
使用一个互斥锁,但是当输入和输出同时发生时,我使用的数据结构是100%安全的;它是队列的一种类型。我认为在填充一些新数据时阻止从队列中读取任何数据,或者反之亦然,这是一种性能折衷

我确实考虑过使用信号量,但问题是,很多C和C++库都没有实现信号量。 那么,如果cond向锁定线程发送信号会发生什么情况呢

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

out()
    outLock.lock()
    while isEmpty
        cond.wait(outLock)
    isEmpty = true
    outLock.unlock()

信号永远丢失了。如果调用
pthread\u cond\u signal
时没有线程在等待信号,那么
pthread\u cond\u signal
什么也不做。

in()
线程设置
isEmpty=false
out()
线程测试
而(isEmpty)
时,必须使用相同的互斥锁。否则,可能发生以下情况:

  • out()
    线程测试
    isEmpty
    ,发现它是真的
  • in()
    
  • out()
    线程调用
    cond.wait()
    并永远阻塞,尽管队列不再为空
  • 请注意,在这个序列中没有出现虚假的唤醒-这只是一个普通的旧的比赛条件


    只要您使用与测试
    isEmpty
    时相同的互斥锁更新
    isEmpty
    ,这种交错就不会发生。

    因为两个不同的线程正在读取和修改
    isEmpty
    ,所以在不受保护的情况下访问它是错误的。当允许
    in
    out
    使用不同的锁实例时,基本上就是这样做的

    在同一条件变量上使用不同的锁实例违反了(emphasis mine)

    对同一条件变量的并发
    pthread_cond_wait()
    pthread_cond_timedwait()
    操作使用多个互斥锁的效果未定义;也就是说,当线程等待条件变量时,条件变量将绑定到唯一的互斥体,而此(动态)绑定将在等待返回时结束