当前位置:  技术问答>linux和unix

看到线程的条件变量这部分时有些糊涂!

    来源: 互联网  发布时间:2016-05-07

    本文导语:  书上说:  条件变量必须和互斥锁配合起来使用,它用于等待,直到某一特定条件为真。对条件变量的cv_wait操作将使线程阻塞,直到所等的条件信号成立后,才能由cv_signal操作将其中的一个阻塞线程唤醒。cv_wait操作...

书上说:

 条件变量必须和互斥锁配合起来使用,它用于等待,直到某一特定条件为真。对条件变量的cv_wait操作将使线程阻塞,直到所等的条件信号成立后,才能由cv_signal操作将其中的一个阻塞线程唤醒。cv_wait操作在阻塞线程前,将对相应的互斥锁执行开锁操作,并在返回前重新对互斥锁进行关锁操作。

  请问:为什么cv_wait操作在阻塞线程前,将对相应的互斥锁执行开锁操作??

|
这跟互斥锁的概念有关,一般来说,互斥锁所包含的代码段是不可重用的,也就是说同一时间只有一个进程能执行该代码段。
cv_wait的作用是条件阻塞当前线程,则势必需要将互斥锁代码段解锁以供别的线程使用(可理解为释放资源),否则会形成死锁,自己被阻塞而别的线程又无法继续执行。
反之cv_wait在条件满足唤醒当前线程之前,应该将互斥锁锁定以便执行该代码段(可理解为占有资源),同时别的进程将不能执行该代码段。

|
不开锁的话,另一个线程没法子进行cv_signal操作。

|
就用操作系统原理中常见的生产者-消费者问题来说:
consumer: 消费者
producer:生成者
number:产品数量

lock: 加锁
unlock: 解锁

wait: 等待
signal: 通知

首先,锁操作是保护number这个共享变量,条件变量的具体含义也是基于number,以下用伪码说明:

consumer() {
while (1) {
            lock      /*为了检查共享变量number是否满足条件,要加锁*/
    
            while ( number == 0 ) {  /*实践中wait可能会由于中断或其它原因返回,如果是由这些异常导致则继续wait,如果确实number
                                      > 0,进行循环后的处理*/
                wait /*只有确定number等于零即没有产品时,才需要wait,否则就完全是浪费;进入wait和解锁是原子操作,是由系统保证
                       的,为什么要解锁?如果不解锁,producer怎么改变number让其大于零以达到signal的目的?不管何种原因wait返
                       回,都会先加锁再返回的,同样是原子操作,由系统保证,为什么加锁?如果不加锁怎么检查number的值?*/
            }
    
            number-- /*取出产品*/
        
            unlock    /*成功取出产品后尽快解锁,提高并发能力*/
        
            /*消费中。。。*/
    }
}
producer() {
while (1) {
            /*生产中。。。*/
    
            lock      /*为了检查共享变量number是否满足条件,要加锁*/
    
            number++  /*加入产品*/
    
            if (number == 1) /*说明生产这个产品前number == 0, 可能有consumer在wait,需要我们signal*/
                signal /*通知consumer*/ 
    
            unlock    /*成功放入产品后尽快解锁,提高并发能力*/
}
}

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 我看到大家都在讨论分数的问题,我如何看到自己的分数呢?
  • 为什么我的Redhat9在窗口模式下可以看到汉字,在命令行模式下就看到乱码?
  • 用浏览器看applet,总是只能看到修改前的applet,关了浏览器,再开,还是只能看到修改前的,难道真的要重启机子?太夸张了
  • 奇怪,CSDN的贴子,提问部分我最多能看到第4行??!!
  • cygwin的ssh中无法看到网络盘
  • 怎么看到自己发过言的帖子?
  • 怎样看到.jar文件的源代码
  • 刚装上linux,我怎样才能看到windows(FAT32)下的文件?
  • 关于bash shell: 用set命令可以看到的信息都储存在哪?
  • windows访问linux ftp却无法看到相关内容
  • ftp 登录,无法看到相关内容。
  • 什么网站可以看到Linux曾经出现过的所有BUG?
  • 请问安装ubuntu的硬盘,如果被拆走的话,是否能看到硬盘上的文件?
  • 在哪里可以看到打印信息??
  • 请问怎样才能看到JavaScript原来的脚本语言?
  • 一个巨大的悲哀啊!看到一篇好文章,结果IE出错了
  • (新手)这里怎么看到300篇以外的所有文章?(不是搜索)
  • 请教一个简单问题,什么命令可以看到目录下的所有用ln建立的联接??谢谢
  • 安装Redhat选者简体中文,执行Xconfigurator,屏幕上看到乱码,如何解决?
  • 请问在red hat8.0下 怎么看到 别的分驱的文件


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3