看过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虚假唤醒相关推荐

  1. java suprious wakeup_多线程编程中条件变量和的spurious wakeup 虚假唤醒

    1. 概述 条件变量(condition variable)是利用共享的变量进行线程之间同步的一种机制.典型的场景包括生产者-消费者模型,线程池实现等. 对条件变量的使用包括两个动作: 1)线程等待某 ...

  2. 多线程并发编程需要注意虚假唤醒Spurious wakeup

    虚假唤醒  Spurious wakeup 如果等待线程在没有通知被调用的情况下唤醒,则称为Spurious wakeup. 解决方案就是: 使用while条件判断,更好的方案是避免使用wait这种低 ...

  3. linux虚假唤醒(spurious wakeup)

    1.Linux对虚假唤醒的说明 On a multi-processor, it may be impossible for an implementation of pthread_cond_sig ...

  4. wait和notify的虚假唤醒(spurious wakeups)

    文章目录 1 现象 2 虚假唤醒 1 现象 这个词的定义来源于JDK的Object#wait()方法的注解 官方API明确的告诉我们,为了防止发生中断错误以及虚假唤醒的问题,我们需要将wait()方法 ...

  5. 条件变量的虚假唤醒(spurious wakeups)问题

    引言 条件变量是我们常用的同步原语之一,它的正确使用方式一般如下图: 在wait端,我们必须把判断布尔条件和wait()放到while循环中,而不能用if语句,原因是可能会引起虚假唤醒. 那么,究竟什 ...

  6. pthread_cond_wait的spurious wakeup问题

    最近在温习pthread的时候,忽然发现以前对pthread_cond_wait的了解太肤浅了.昨晚在看<Programming With POSIX Threads>的时候,看到了pth ...

  7. Java多线程之线程虚假唤醒

    Java多线程之线程虚假唤醒 本文目录提纲 问题:两个线程对一个初始值为零的变量操作,实现一个线程加一,另一个线程减一,来十次. 问题:四个线程对一个初始值为零的变量操作,实现两个线程加一,另外两个线 ...

  8. java线程打水问题_Java 多线程 wait() 虚假唤醒问题

    本文分享 wait()  的虚假唤醒(Spurious Wakeups)问题,会说明什么是虚假唤醒,以及如何解决. 先看一下相关的 java doc: java doc 说由于中断和虚假唤醒可能会发生 ...

  9. C++条件变量Wait及虚假唤醒

    (1) wait(lock): 调用时即阻塞线程,并且调用lock.unlock() (2) wait(lock, conditions): 调用时检查conditions,如果为false,则阻塞线 ...

  10. java中wait和notify的虚假唤醒问题

    前言 本篇博客来自 https://www.cnblogs.com/clover-forever/p/12616869.html 自己在此记录一下,方便日后复习. 虚假唤醒的概念 jdk官方文档解释: ...

最新文章

  1. 聊聊找工作中的项目经验问题(推荐系统和智能问答)
  2. spring中getBeansWithAnnotation(Class<? extends Annotation> annotationType)方法
  3. wxWidgets:wxHelpEvent类用法
  4. 对一个简单汇编程序分析
  5. 淘宝直播应关注哪些方面?
  6. 在线手机号码VCF批量导入工具
  7. Unet实现文档图像去噪、去水印
  8. c51单片机时钟程序汇编语言,51单片机汇编语言--延时程序的延时时间
  9. C#对文件的操作(创建、获取文件数量、删除)(读、写文件)
  10. 数据分类分级指南范围
  11. BackgroundWorker线程控件用法
  12. SPARC架构下的反汇编(三)——SPARC汇编语言
  13. 拼点游戏(类似于田忌赛马)
  14. Hey 朋友们好久不见。
  15. windows管理右键新建的方法
  16. 【Axure教程】中继器表格自动合计模板
  17. 查看linux运存_linux如何查看内存?
  18. 浅谈决策、管理与信息化的关系
  19. React项目-点餐后台管理系统-react框架实现后台管理系统(包含权限处理)--新手入坑必看!(一)
  20. CAS原理分析及ABA问题详解

热门文章

  1. 用excel打开txt文件
  2. java的泛型方法_Java中的泛型方法
  3. OSChina 周五乱弹 —— 奴家一时失手,官人休怪
  4. 好用的在线ide------ideone
  5. JAVA企业微信事件接收
  6. canvas 踩坑 * 小球弹性碰撞逻辑解析
  7. 有道智云翻译API + retrofit实现在线翻译Android app
  8. Android Dialog宽度设置固定大小
  9. ThinkPHP5.0 查询条件where()使用
  10. 三阶魔方还原教程最详细