我正在编写一个使用pthread_cond与互斥量相结合的多线程代码,这让我很奇怪:
是一次信号,所以如果在另一个线程等待之前发送信号,另一个线程会无限期地等待吗?
由于cond_wait()解锁互斥锁,在mutex_unlock()之前编写此语句是否是一个拇指规则,(我意识到这会使后者变得多余,但我只是为了清晰起见)或者有很多您希望在互斥锁之外编写函数的场景吗?
答案 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_*
次呼叫的返回值;返回值是关于您始终需要知道的状态的重要信息,并且几乎总是需要采取行动。
一些有用的手册页(用于返回值):