spurious wakeup虚假唤醒
看过apue大家都知道互斥器用于排他性的访问共享数据而不是等待原语,如果需要等待某个条件发生需要用条件变量。而当用条件变量的时候需要检查某个布尔表达式是否为真,进行这项检查的时候需要互斥器来保护,所以此时互斥器和条件变量联合起来用于同步。
互斥器和条件变量用法如下:
pthread_mutex_lock(&lock);
while (condition_is_false) {
pthread_cond_wait(&cond, &lock);
}
上面那个while能换成if吗?答案是不能,否则会导致spurious wakeup虚假唤醒。因为不仅要在pthread_cond_wait前要检查条件是否成立,在pthread_cond_wait之后也要检查。因为pthread_cond_wait不仅能被pthread_cond_signal/pthread_cond_broadcast唤醒,而且还会被其它信号唤醒,后者就是虚假唤醒。
linux的pthread_cond_wait是用futex系统调用,这个是慢速系统调用,看过apue知道任何慢速系统调用被信号打断的时候会返回-1,并且把errno置为EINTR,如果慢速系统调用的重启功能被关闭,需要在调用该系统调用的地方手动重启它,像下面这样:
while (1) {
int ret = syscall();
if (ret < 0 && errno == EINTR)
continue;
else
break;
}
但是futex不能这么用,因为futex结束后到再次重启这个过程有个时间窗,在这个窗口内可能发生了pthread_cond_signal/phread_cond_broadcast,如果发生这种情况,再进行pthread_cond_wait的时候就错过了一次条件变量的变化,就会无限等待下去。但是如果不像上面那样写又无法重启futex系统调用,咋整呢?这就回到了上面检查布尔条件的时候为什么用while而不用if。
用while不会因为虚假唤醒而错过phread_cond_signal/pthread_cond_broadcast,而且在通过判断while条件不成立检测出此次唤醒为虚假唤醒并继续调用futex继续等待。
spurious wakeup虚假唤醒相关推荐
- java suprious wakeup_多线程编程中条件变量和的spurious wakeup 虚假唤醒
1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1)线程等待某 ...
- 多线程并发编程需要注意虚假唤醒Spurious wakeup
虚假唤醒 Spurious wakeup 如果等待线程在没有通知被调用的情况下唤醒,则称为Spurious wakeup. 解决方案就是: 使用while条件判断,更好的方案是避免使用wait这种低 ...
- linux虚假唤醒(spurious wakeup)
1.Linux对虚假唤醒的说明 On a multi-processor, it may be impossible for an implementation of pthread_cond_sig ...
- wait和notify的虚假唤醒(spurious wakeups)
文章目录 1 现象 2 虚假唤醒 1 现象 这个词的定义来源于JDK的Object#wait()方法的注解 官方API明确的告诉我们,为了防止发生中断错误以及虚假唤醒的问题,我们需要将wait()方法 ...
- 条件变量的虚假唤醒(spurious wakeups)问题
引言 条件变量是我们常用的同步原语之一,它的正确使用方式一般如下图: 在wait端,我们必须把判断布尔条件和wait()放到while循环中,而不能用if语句,原因是可能会引起虚假唤醒. 那么,究竟什 ...
- pthread_cond_wait的spurious wakeup问题
最近在温习pthread的时候,忽然发现以前对pthread_cond_wait的了解太肤浅了.昨晚在看<Programming With POSIX Threads>的时候,看到了pth ...
- Java多线程之线程虚假唤醒
Java多线程之线程虚假唤醒 本文目录提纲 问题:两个线程对一个初始值为零的变量操作,实现一个线程加一,另一个线程减一,来十次. 问题:四个线程对一个初始值为零的变量操作,实现两个线程加一,另外两个线 ...
- java线程打水问题_Java 多线程 wait() 虚假唤醒问题
本文分享 wait() 的虚假唤醒(Spurious Wakeups)问题,会说明什么是虚假唤醒,以及如何解决. 先看一下相关的 java doc: java doc 说由于中断和虚假唤醒可能会发生 ...
- C++条件变量Wait及虚假唤醒
(1) wait(lock): 调用时即阻塞线程,并且调用lock.unlock() (2) wait(lock, conditions): 调用时检查conditions,如果为false,则阻塞线 ...
- java中wait和notify的虚假唤醒问题
前言 本篇博客来自 https://www.cnblogs.com/clover-forever/p/12616869.html 自己在此记录一下,方便日后复习. 虚假唤醒的概念 jdk官方文档解释: ...
最新文章
- 聊聊找工作中的项目经验问题(推荐系统和智能问答)
- spring中getBeansWithAnnotation(Class<? extends Annotation> annotationType)方法
- wxWidgets:wxHelpEvent类用法
- 对一个简单汇编程序分析
- 淘宝直播应关注哪些方面?
- 在线手机号码VCF批量导入工具
- Unet实现文档图像去噪、去水印
- c51单片机时钟程序汇编语言,51单片机汇编语言--延时程序的延时时间
- C#对文件的操作(创建、获取文件数量、删除)(读、写文件)
- 数据分类分级指南范围
- BackgroundWorker线程控件用法
- SPARC架构下的反汇编(三)——SPARC汇编语言
- 拼点游戏(类似于田忌赛马)
- Hey 朋友们好久不见。
- windows管理右键新建的方法
- 【Axure教程】中继器表格自动合计模板
- 查看linux运存_linux如何查看内存?
- 浅谈决策、管理与信息化的关系
- React项目-点餐后台管理系统-react框架实现后台管理系统(包含权限处理)--新手入坑必看!(一)
- CAS原理分析及ABA问题详解