博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
条件变量
阅读量:4114 次
发布时间:2019-05-25

本文共 2182 字,大约阅读时间需要 7 分钟。

MY:

条件变量主要用于线程间同步,并且配合互斥锁一起使用,考虑当一个线程p负责对共享区域进行操作(比如修改变量的值),另一个线程q判断变量的值是否达到了某个特定的值,并且到达的话输出“YES”语句,如果不用条件变量,仅用互斥锁的话,q需要不断轮询变量是否满足要求,这就消耗了大量的CPU资源,考虑条件变量,首先q抢占锁,检测变量的值,若不符合条件,则在释放锁之后阻塞自己(这两个操作设为一个原子操作),线程p开始抢占锁,然后处理,出来后释放锁,并且检测是否为某个特定的值,如果是的话,那么给被阻塞线程发送信号,被阻塞线程收到信号后,立即解除阻塞并抢占锁(也是原子操作),然后输出变量,最后释放锁。

参考:

很显然,pthread中的条件变量与Java中的wait,notify类似

假设有共享的资源sum,与之相关联的mutex 是lock_s.假设每个线程对sum的操作很简单的,与sum的状态无关,比如只是sum++.那么只用mutex足够了.程序员只要确保每个线程操作前,取得lock,然后sum++,再unlock即可.每个线程的代码将像这样add()

{
  pthread_mutex_lock(lock_s);
  sum++;
  pthread_mutex_unlock(lock_s);
}

  如果操作比较复杂,假设线程t0,t1,t2的操作是sum++,而线程t3则是在sum到达100的时候,打印出一条信息,并对sum清零.这种情况下,如果只用mutex, 则t3需要一个循环,每个循环里先取得lock_s,然后检查sum的状态,如果sum>=100,则打印并清零,然后unlock.如果sum<100,则unlock,并sleep()本线程合适的一段时间.

 这个时候,t0,t1,t2的代码不变,t3的代码如下

  print()
  {
    while (1)
    {
      pthread_mutex_lock(lock_s);
      if(sum<100)
      {
        printf(“sum reach 100!”);
        pthread_mutex_unlock(lock_s);
      }
      else
      {
        pthread_mutex_unlock(lock_s);
        my_thread_sleep(100);
        return OK;
      }
    }
  }

这种办法有两个问题

  1) sum在大多数情况下不会到达100,那么对t3的代码来说,大多数情况下,走的是else分支,只是lock和unlock,然后sleep().这浪费了CPU处理时间.
  2) 为了节省CPU处理时间,t3会在探测到sum没到达100的时候sleep()一段时间.这样却又带来另外一个问题,亦即t3响应速度下降.可能在sum到达200的时候,t3才会醒过来.
  3) 这样,程序员在设置sleep()时间的时候陷入两难境地,设置得太短了节省不了资源,太长了又降低响应速度.真是难办啊!

  这个时候,condition variable内裤外穿,从天而降,拯救了焦头烂额的你.

  你首先定义一个condition variable.

  pthread_cond_t cond_sum_ready=PTHREAD_COND_INITIALIZER;

  t0,t1,t2的代码只要后面加两行,像这样

  add()
  {
    pthread_mutex_lock(lock_s);
    sum++;
    pthread_mutex_unlock(lock_s);
    if(sum>=100)
    pthread_cond_signal(&cond_sum_ready);
  }
  而t3的代码则是
  print
  {
    pthread_mutex_lock(lock_s);
    while(sum<100)
    pthread_cond_wait(&cond_sum_ready, &lock_s);
    printf(“sum is over 100!”);
    sum=0;
    pthread_mutex_unlock(lock_s);
    return OK;
  }

注意两点:

  1) 在thread_cond_wait()之前,必须先lock相关联的mutex, 因为假如目标条件未满足,pthread_cond_wait()实际上会unlock该mutex, 然后block,在目标条件满足后再重新lock该mutex, 然后返回.

  2) 为什么是while(sum<100),而不是if(sum<100) ?这是因为在pthread_cond_signal()和pthread_cond_wait()返回之间,有时间差,假设在这个时间差内,还有另外一个线程t4又把sum减少到100以下了,那么t3在pthread_cond_wait()返回之后,显然应该再检查一遍sum的大小.这就是用while的用意

转载地址:http://dogsi.baihongyu.com/

你可能感兴趣的文章
eclipse 如何创建dynamic web project
查看>>
ssh struts+spring+hibernate 官方下载地址
查看>>
web开发常用jar包 常用jar包
查看>>
SSH三大框架的工作原理及流程
查看>>
eclipse为SSH框架.xml文件添加自动提示功能
查看>>
ssh整合常见的错误
查看>>
Finding and Installing a NuGet Package Using the Package Manager Console
查看>>
Ext.NET第一个项目的安装环境配置
查看>>
EXT.NET--FORM控件
查看>>
Ext.NET事件
查看>>
JS获取页面EXT.NET控件
查看>>
Ext.net中如何使用Extjs代码
查看>>
Ext.Net传递参数
查看>>
Ext.NET -- 后台动态添加控件
查看>>
gridPanel事件--初学ext.net框架
查看>>
java中常被忽略的几个问题
查看>>
java Math.round()比较特殊的四舍五入
查看>>
面试题java
查看>>
postgreSql的字符串操作函数
查看>>
postgreSQL 类型转换
查看>>