条件变量的虚假唤醒(spurious wakeups)问题_c++的条件变量什么情况下会被虚假唤醒_li27z的博客-程序员宅基地

引言

条件变量是我们常用的同步原语之一,它的正确使用方式一般如下图:

这里写图片描述

在wait端,我们必须把判断布尔条件和wait()放到while循环中,而不能用if语句,原因是可能会引起虚假唤醒。
那么,究竟什么是虚假唤醒,导致虚假唤醒的原因又是什么呢?

什么是虚假唤醒?

举个例子,我们现在有一个生产者-消费者队列和三个线程。

1) 1号线程从队列中获取了一个元素,此时队列变为空。

2) 2号线程也想从队列中获取一个元素,但此时队列为空,2号线程便只能进入阻塞(cond.wait()),等待队列非空。

3) 这时,3号线程将一个元素入队,并调用cond.notify()唤醒条件变量。

4) 处于等待状态的2号线程接收到3号线程的唤醒信号,便准备解除阻塞状态,执行接下来的任务(获取队列中的元素)。

5) 然而可能出现这样的情况:当2号线程准备获得队列的锁,去获取队列中的元素时,此时1号线程刚好执行完之前的元素操作,返回再去请求队列中的元素,1号线程便获得队列的锁,检查到队列非空,就获取到了3号线程刚刚入队的元素,然后释放队列锁。

6) 等到2号线程获得队列锁,判断发现队列仍为空,1号线程“偷走了”这个元素,所以对于2号线程而言,这次唤醒就是“虚假”的,它需要再次等待队列非空。

使用while()判断的原因

在多核处理器下,pthread_cond_signal可能会激活多于一个线程(阻塞在条件变量上的线程)。结果就是,当一个线程调用pthread_cond_signal()后,多个调用pthread_cond_wait()或pthread_cond_timedwait()的线程返回。这种效应就称为“虚假唤醒”。

Linux man page中也有提到:
虚假唤醒造成的后果:
这里写图片描述
需要对条件进行再判断以避免虚假唤醒:
这里写图片描述

如果用if判断,多个等待线程在满足if条件时都会被唤醒(虚假的),但实际上条件并不满足,生产者生产出来的消费品已经被第一个线程消费了。
这就是我们使用while去做判断而不是使用if的原因:因为等待在条件变量上的线程被唤醒有可能不是因为条件满足而是由于虚假唤醒。所以,我们需要对条件变量的状态进行不断检查直到其满足条件,不仅要在pthread_cond_wait前检查条件是否成立,在pthread_cond_wait之后也要检查。


参考资料:
http://stackoverflow.com/questions/8594591/why-does-pthread-cond-wait-have-spurious-wakeups

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Leeds1993/article/details/52738845

智能推荐

去掉msvcr90的依赖以及atl90.dll的依赖-程序员宅基地

这个提示给出了很详细的答案,就是“应用程序配置不正确”。什么是应用程序配置不正确?就是缺少这个OCX控件以及其外部链接的DLL所依赖的相关运行库DLL;一般来说,这种现象出现在用VC2008编译的OCX或其外部链接的DLL工程上。通过一一查看OCX及其外部链接的DLL项目依赖DLL,果然有一个是由VC2008编译的,它的DLL依赖: 这个模块的程序员确定他的

mingw clang compiler-rt 编译错误-程序员宅基地

错误信息提示如下:[ 0%] Built target compiler-rt-headers[ 0%] Building C object projects/compiler-rt/lib/CMakeFiles/clang_rt.i386.dir/enable_execute_stack.c.objD:\llvm-3.3.src\projects\compiler-rt\lib\

Apache服务器虚拟主机和别名配置及问题_apache虚拟主机设置别名-程序员宅基地

1.配置虚拟主机在hosts文件创建虚拟主机的名称和IP地址,如下图:127.0.0.1 www.dangdang.com hosts文件位置:C:\Windows\System32\drivers\etc\修改Apache的虚拟主机的配置文件httpd-vhosts.conf,位置:eg:E:\xampp\apache\conf\extra\ NameV_apache虚拟主机设置别名

CSS知识点整理及属性整理_要求整理出所学的css属性及其属性值信息的方法-程序员宅基地

CSS简介CSS指层级样式表(Cascading Style Sheets)样式定义如何显示在HTML元素样式通常储存在样式表中把样式添加到HTML4.0中,是为了解决内容和表现分离的问题外部样式表可以极大提高工作效率外部样式表通常储存在CSS文件中多个样式定义可层叠为一提示所有的主流浏览器均支持层叠样式表层叠次序,优先级依次增高浏览器缺省设置外部样式表内部样..._要求整理出所学的css属性及其属性值信息的方法

基于javaweb的小说阅读管理系统(java+jsp+bootstrap+servlet+mysql)_小说阅读系统-程序员宅基地

基于javaweb的小说阅读管理系统(java+jsp+bootstrap+servlet+mysql)运行环境Java≥8、MySQL≥5.7、Tomcat≥8开发工具eclipse/idea/myeclipse/sts等均可配置运行适用课程设计,大作业,毕业设计,项目练习,学习演示等功能说明_小说阅读系统

性能测试、负载测试、强度测试、容量测试的区别_仪器验证满载和负载的区别-程序员宅基地

性能测试(或称多用户并发性能测试)、负载测试、强度测试、容量测试是性能测试领域里的几个方面,但是概念很容易混淆。下面将几个概念进行介绍。 性能测试(Performance Test):通常收集所有和测试有关的所有性能,通常被不同人在不同场合下进行使用。 关注点:how much和how fast 负载测试(Load Test):负载测_仪器验证满载和负载的区别

随便推点

GDPR个人数据处理的6大原则包含哪些内容?_gdpr原则-程序员宅基地

个人数据的处理问题作为欧盟GDPR的重点规制对象,其相关原则的规定被放在了该条例原则部分的首要位置。随着我国经济主体与欧盟各成员国之间往来的日益频繁,学习欧盟GDPR的相关内容对企业发展至关重要。今天SCA安全通信联盟为大家整理了GDPR中个人数据处理的6大原则——“合法公平透明”、“目的限制”、“数据最小化”、“准确性”、“储存限额”、“完整性和机密性”。互联网让我们的世界越来越联动,为了在..._gdpr原则

uniapp 横屏开发页面配置(仅支持App、H5)_uniapp横屏开发-程序员宅基地

目录1、pages.json页配置页面大小2、manifest.json文件修改3、App.vue文件配置 4、配置单位提示在uniapp官网中提到了pages.json页面对于横屏页面单位的配置参考官网这篇详解 https://uniapp.dcloud.net.cn/adapt由于我开发的横屏项目的横屏设计图分辨率以及硬件分辨率是1280*800,所以我的页面配置是2、manifest.json文件修改打开manifest.json文件,如图:在源码视图的"app-plus"里添加子项3_uniapp横屏开发

tensorflow2.2_保存和加载_爱听许嵩歌的博客-程序员宅基地

使用mnist数据集作为示例import osimport tensorflow as tffrom tensorflow import keras# 使GPU显存不被占满os.environ['CUDA_VISIBLE_DEVICES'] = "0" # GPU的编号config = tf.compat.v1.ConfigProto()config.gpu_options.visible_device_list = '0' # GPU的编号config.gpu_options.al

VC++更改鼠标指针为系统预定义形状和自定义形状_idc_cross_bcbobo21cn的博客-程序员宅基地

新建一个单文档工程;为视类添加WM_SETCURSOR消息处理函数;设置鼠标指针为IDC_CROSS,这是系统预定义的,十字形;LoadCursor载入系统预定义光标时,第一个参数为NULL;预定义,等待光标;有的电脑是沙漏形状,有的是一个转圈的圆;系统预定义光标如下; IDC_APPSTARTING 标准的箭头和小沙漏 IDC_ARROW 标准的箭头 IDC_CROSS 十字光标 IDC_HAND Windows 98/Me, Windows 20..._idc_cross

WIN8环境下PublicKeyToken=b77a5c561934e089”类型的权限已失败。-程序员宅基地

今天上午运行还好好的,下午运行就出现如下问题:请求“System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限已失败。考虑到是权限,所以在网上搜了半天,用了很多办法都不行。后来采用管理员运行的方式,竟然不报错了!_b77a5c561934e089

RoBERTa中的merge.txt和vocab.json是什么?_roberta-cbi-ei-程序员宅基地

背景在使用其他组织或个人发布的RoBERTa预训练模型时,一般除了模型文件之外还会有merges.txt和vocab.json。相比于BERT只需要一个vocab.txt,为何RoBRETa需要2个?作用是什么?说明Bert采用的是字符级别的BPE编码,直接生成词表文件。Roberta采用的是**byte level的BPE(BBPE)**编码,预训练结果中的merges.txt中存储了BBPE过程中merge得到的所有token,可以简单理解成就是字典。vocab.json则是一个字典中基本单元到索_roberta-cbi-ei