linux
os / linux / pthread-凯发ag旗舰厅登录网址下载
栗子:
mutex.lock();while (判断“条件”是否成立) {pthread_cond_wait 等待 }mutext.unlock();条件变量这个互斥锁,不是用来保护条件变量的内部状态。而是用来保护外部“条件”(就是那个 while 循环中的判断)。假如条件变量的内部状态需要锁定,完全可以在内部实现中维护一个锁,没有必要从外部传进来。
用于判断是否等待的“条件”,通常就是线程之间共享的某个变量值。a 线程判断“条件”等待,会读取共享变量。b 线程让“条件”满足,会修改变量。这个锁,就是保护线程间的共享变量(“条件”),让“条件”不会一边修改,一边读取。
这把锁还有个额外的作用。wait 函数会阻塞,将线程 a 放到阻塞队列中。wait 函数放在锁的 lock,unlock 内部,也保证了线程还没有真正放到阻塞队列时,线程 b 不能修改“条件”后进行唤醒。这段话应该暂时读不懂,可回头再看,先放在这里,不然描述就不够准确。
不同的应用会有不同的“条件”,在实现条件变量这个库时,是没有办法预先知道这个“条件”究竟是什么。因此要保护“条件”,就只能让用户自己在库外部分配锁。
弄清了这个互斥锁究竟在保护什么。这时我们才能进一步讨论 pthread_cond_wait 为什么要传入这个锁呢?这点就跟 wait 的实现有关。
先来看等待线程 a 的写法。
mutex.lock();while (判断“条件”是否成立) {pthread_cond_wait 等待 }mutext.unlock();判断“条件”是否成立,在 lock, unlock 之间受到保护。pthread_cond_wait 可能会阻塞,假如真的阻塞,mutex 这锁就一直不能被释放了。因此在 pthread_cond_wait 的实现内部,在阻塞之前,必须先将锁释放。在唤醒的时候,再重新获取锁。
将 pthread_cond_wait 展开,内部实现中,会有下面的过程。
做一些其它事情 mutext.unlock() 阻塞中... 唤醒 mutext.lock()假如在线程 a 中完全展开 pthread_cond_wait。
mutex.lock();while (判断“条件”是否成立) {做一些其它事情mutext.unlock()阻塞唤醒mutext.lock() }mutext.unlock();可以看到,判断“条件” 一直在 mutext 的 lock, unlock 之间,受到保护。
来到这里,我们总结一下。
注意上面第 2 点中,“适当时机”这个词。假如不将这个锁传入 pthread_cond_wait,让用户自己在阻塞前先释放锁,是没有办法做到适当时机的。阻塞队列在条件变量库内部维护,只有条件变量库内部才能控制这个时机。
wait 会阻塞,将线程 a 放到阻塞队列中。在线程还没有真正放到阻塞队列时,需要一直上锁。不然另一线程 b 修改“条件”后进行唤醒,这个线程 a 还没有在阻塞队列中,就不能被唤醒了。因而这把保护外部判断“条件”的锁,需要传入到 wait 函数中。等将线程真正放到阻塞队列后才能解锁,之后线程被唤醒后再重新获取。
线程 a 的 pthread_cond_wait 需要传入 mutext,并且 pthread_cond_wait 一定要在 lock 和 unlock 之间。
至于线程 b, 用于修改“条件”。修改“条件” 也必须在 lock 和 unlock 之间,受互斥锁保护。至于 pthread_cond_signal 是否在 lock 和 unlock 之间,其实是没有关系的。但 pthread_cond_signal 必须在修改“条件”之后,不然可能 a 线程被唤醒后,条件不满足继续等待,这个唤醒信号就丢失了。
mutext.lock() 修改”条件“ pthread_cond_signal 唤醒 mutext.unlock()也可以将 pthread_cond_signal 移到 unlock 外部。
mutext.lock() 修改”条件“ mutext.unlock() pthread_cond_signal 唤醒条件变量等待时,那个 wait 的判断,需要使用 while 循环,而不是 if,是防止虚假唤醒。就不再一一分析了。
作者:黄兢成
链接:https://www.zhihu.com/question/24116967/answer/676751734
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(saw:game over!)
总结
以上是凯发ag旗舰厅登录网址下载为你收集整理的os / linux / pthread_cond_wait 为什么需要传递 mutex 参数?的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得凯发ag旗舰厅登录网址下载网站内容还不错,欢迎将凯发ag旗舰厅登录网址下载推荐给好友。
- 上一篇:
- 下一篇: