欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 运维知识 > linux >内容正文

linux

os / linux / pthread-凯发k8官方网

发布时间:2024/10/14 linux 25 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 os / linux / pthread_cond_wait 为什么需要传递 mutex 参数? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

栗子:

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 之间,受到保护。

来到这里,我们总结一下。

  • 跟条件变量关联的互斥锁,是用于保护判断“条件”,并非条件变量的内部状态。
  • 将互斥锁,传入 wait 的实现中,是让条件变量库可以在适当的时机释放(unlock)和重新获取(lock)这把锁。
  • 注意上面第 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!)

    总结

    以上是凯发k8官方网为你收集整理的os / linux / pthread_cond_wait 为什么需要传递 mutex 参数?的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

    • 上一篇:
    • 下一篇:
    网站地图