zoukankan      html  css  js  c++  java
  • 条件变量(三)

    条件变量(二)这边文章主要纠结了pthread_cond_wait(&cond,&mutex)函数以及为何判断条件时要用while而不是if。

    本文还想弄清楚另外两个关于pthread_cond_signal(&cond)的问题:

    1、先改变条件值还是先调用pthread_cond_signal?

    2、pthread_cond_signal写在临界区内还是临界区外?

    问题一:先改变条件值还是先调用pthread_cond_signal?

    其实都一样,因为已经持有锁了。在没有锁的情况下改变条件本来就很危险。当然可以在没有锁的情况下调用signal或者broadcast函数。

    1 void signal()
    2 {
    3     pthread_mutex_lock(&mutex);
    4     signaled = true;
    5     pthread_cond_signal(&cond); //顺序可以调整
    6     pthread_mutex_unlock(&mutex);
    7 }

    这个问题本人在github上请教过陈硕大神,见https://github.com/chenshuo/recipes/issues/18。在持有锁的情况下,没有其他线程可以从wait返回,因为阻塞在mutex_lock队列中,在等待锁,因为wait出来后要加锁:

    1 void broadcast()
    2 {
    3     pthread_mutex_lock(&mutex_);
    4     pthread_cond_broadcast(&cond_);
    5     signaled_ = true;
    6     pthread_mutex_unlock(&mutex_);
    7 }

    问题二:pthread_cond_signal写在临界区内还是临界区外?

    这两种写法都见到过,也都正确,但各有缺点。

    一、在临界区内调用pthread_cond_signal:

    1 void signal()
    2 {
    3     pthread_mutex_lock(&m);
    4     signaled = true; 
    5     pthread_cond_signal(&cond);
    6     pthread_mutex_unlock(&m);
    7 }

    缺点是线程A的signal唤醒另外一个线程B的wait时,wait要加锁,此时互斥锁有可能仍然被线程A持有,导致线程B再次陷入内核,影响性能。但是在LinuxThreads或者NPTL里面,就不会有这个问题,因为在Linux 线程中,有两个队列,分别是cond_wait队列和mutex_lock队列, cond_signal只是让线程从cond_wait队列移到mutex_lock队列,而不用返回到用户空间,不会有性能的损耗。操。那讨论个蛋。(思考:线程A最后释放的锁一定会被线程B得到吗?就不会被别的线程得到?若不能保证B等到A释放的锁,岂不是一次虚假唤醒?)

    二、在临界区外调用pthread_cond_signal:

    1 void signal()
    2 {
    3     pthread_mutex_lock(&m);
    4     signaled = true;  
    5     pthread_mutex_unlock(&m);
    6     pthread_cond_signal(&cond);
    7 }

    缺点是在线程A unlock和signal之前有一个低优先级的线程1 在mutex_lock内等待,接下来线程A执行unlock,再执行signal。线程2上的wait被唤醒,企图加锁。此时线程1和2构成了竞态关系,可能会导致低优先级的线程1先执行,而高优先级的线程2后执行。

  • 相关阅读:
    python 矩阵转置
    go
    Go-GRPC 初体验
    SpringMVC笔记——Spring+MyBatis组合开发简单实例
    MyBatis笔记——EhCache二级缓存
    MyBatis笔记——Mapper动态代理
    MyBatis笔记——初次环境配置
    Spring笔记——配置Hibernate框架事务
    Hibernate笔记——关联关系配置(一对多、一对一和多对多)
    Mysql笔记——触发器简单实例
  • 原文地址:https://www.cnblogs.com/howo/p/8586484.html
Copyright © 2011-2022 走看看