当前位置:网站首页 > 编程语言 > 正文

条件变量的使用(条件变量的使用方法)



等待条件变量的正确姿势:

1)必须使用while循环来等待条件变为真,即醒来之后要立马再判断一次条件是否成立再决定是否需要继续等待,

因为很有可能条件并不为真,但是线程却被各种奇怪的中断或者pthread_cond_broadcast这样的东西给唤醒了

2)至于condition.wait()的作用是提供一个原子操作

进入condition.wait() 时,将 wait 和 mutex.unlock 两步变成一个原子操作,确保在线程进入 wait 之前不会释放锁,也就是保证了在进入 wait 之前没有人能够改动 wait_flag (所有对 wait_flag的操作都要加锁,否则条件变量没有意义),

因为pthread_cond_signal这类函数只会唤醒已经在等待队列里的线程,如果这两步不是原子操作,那么在释放锁之后,进入等待队列之前的这段时间里,有人调用了cond_signal之后也不会被唤醒

触发条件的正确姿势:

通常在资源可用时使用signal,在改变状态时使用broadcast。

这里特别说明一下网上流传的阻塞队列 (为简单起见,这里假设队列最大长度为无限长) 的实现有个错误:

因为pthread_cond_signal只是唤醒线程到就绪队列,至于这个线程能不能抢到锁以及抢到锁之后能不能保证立马被调度并从队列里取元素就不保证了。

所以会出现这种情况,有多个饥饿的线程在等待队列变成非空,这个时候有一个线程放进去一个元素,之后唤醒了一个等待线程到就绪队列,但是他却没有获取到锁,

这个时候其他的线程往队列里push的时候,由于消费者线程没有来得及取元素,所以队列元素的总量大于1,所以并不触发signal。。。

这就导致在下次队列变为空之前,可能只有一个消费者线程会被唤醒。

使用notifyAll可以避免这个问题,但是代价是虚假唤醒(据说对这种情况会优化,这里不讨论。。恩,因为我特么也是不懂啊,记住正确的做法不就好了么)

所以对于有多个消费者线程的阻塞队列,正确的写法是每次push都进行一次notify(),而不是队列为空时才notify

到此这篇条件变量的使用(条件变量的使用方法)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 域名 ip解析(ip域名解析是什么意思)2025-11-26 13:45:06
  • 腾讯视频会员怎么共享给别人登录(腾讯视频会员怎么共享给别人登录电脑)2025-11-26 13:45:06
  • esp32 天气时钟(esp32天气时钟代码下载)2025-11-26 13:45:06
  • 带颜色的网站(带颜色的网站www)2025-11-26 13:45:06
  • 手机被恶意发送验证码怎么回事(手机一直被恶意发验证短信怎么解决)2025-11-26 13:45:06
  • tmm审稿周期(tmi审稿周期)2025-11-26 13:45:06
  • 左斜杠 右斜杠(左斜杠 右斜杠打一字谜)2025-11-26 13:45:06
  • kubelet日志文件存在哪里(kubelet 日志)2025-11-26 13:45:06
  • 本机信息安装(安装信息是什么文件)2025-11-26 13:45:06
  • 左斜杠符号是什么意思(斜杠符号是什么意思驾照)2025-11-26 13:45:06
  • 全屏图片