Posix线程同步基元:pthread_cond_signal()和pthread_cond_wait()

时间:2016-02-18 16:49:18

标签: multithreading pthreads

我正在编写一个使用pthread_cond与互斥量相结合的多线程代码,这让我很奇怪:

  1. 是一次信号,所以如果在另一个线程等待之前发送信号,另一个线程会无限期地等待吗?

  2. 由于cond_wait()解锁互斥锁,在mutex_unlock()之前编写此语句是否是一个拇指规则,(我意识到这会使后者变得多余,但我只是为了清晰起见)或者有很多您希望在互斥锁之外编写函数的场景吗?

1 个答案:

答案 0 :(得分:1)

将此作为你的口头禅:

  

只有等待 某事......

等待应该几乎总是这样:

if (pthread_mutex_lock(...) != 0) {
    /* something terrible happened, panic */
}

while (test-condition) {
    pthread_cond_wait(...)
}

pthread_mutex_unlock(...)

如果对test-condition的独占检查失败,并且上下文输入pthread_cond_wait,则相关联的互斥锁将自动解锁。

这意味着另一个上下文可以输入如下代码:

if (pthread_mutex_lock(...) != 0) {
    /* panic */
}

test-condition = false;

pthread_cond_signal(...);

pthread_mutex_unlock(...);

更改谓词并原子地唤醒调用pthread_cond_wait中的第一个上下文,然后检查谓词test-condition并跳过循环。

如果我们再看一下等待代码:

if (pthread_mutex_lock(...) != 0) {
    /* something terrible happened, panic */
}

while (test-condition) {
    pthread_cond_wait(...)
}

pthread_mutex_unlock(...)

在等待和解锁的呼叫之间,总是有排他性;要么是因为互斥锁是专门获取的(未输入谓词等待循环),要么是因为在从pthread_cond_wait调用返回之前,互斥锁是以原子方式重新获取的。

同步很难做到,并且对于多线程应用程序而言代价很高;应该尝试保持关键部分简单,将误差范围挤压到最小尺寸。

另一件重要的事情是检查所有这些pthread_*次呼叫的返回值;返回值是关于您始终需要知道的状态的重要信息,并且几乎总是需要采取行动。

一些有用的手册页(用于返回值):