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

问使用 posix 条件变量的问题

    来源: 互联网  发布时间:2016-03-27

    本文导语:  先贴一段代码: 1> pthread_mutex_t count_lock; 2> pthread_cond_t count_nonzero; 3> unsigned count; 4> 5> decrement_count() 6> { 7>    pthread_mutex_lock(&count_lock); 8>    while (count == 0) 9>        pthread_cond_wait(&count_nonzero, &count_lock); 1...

先贴一段代码:
1> pthread_mutex_t count_lock;
2> pthread_cond_t count_nonzero;
3> unsigned count;
4>
5> decrement_count()
6> {
7>    pthread_mutex_lock(&count_lock);
8>    while (count == 0)
9>        pthread_cond_wait(&count_nonzero, &count_lock);
10>    count = count - 1;
11>    pthread_mutex_unlock(&count_lock);
12> }

问题:1.当线程阻塞在cond_wait后,如果这时收到了cond_signal,它的状态即变为就绪态,等到CPU资源后就可以向下执行,并不是接收到signal后立即转为执行。其它线程也有可能先于它被唤醒,对count进行操作。这样理解对吗?
      2.关于阻塞在cond_wait的线程,接收到cond_signal并且分到CPU后的执行顺序:
        它是返回到第7行加锁,然后再执行第8行判断count是否为零呢,还是在cond_wait中自动完成加锁及判断条件?我试着在第8行和第9行之间加了一条print语句,线程被唤醒后并没有再次执行这条语句,说明再次锁mutex和条件判断是cond_wait自动完成的,那他是怎么知道判断条件的呢?

|
8>    while (count == 0)
9>        pthread_cond_wait(&count_nonzero, &count_lock); 

上面的代码执行循序是:
先判断count == 0,如果为真,则执行pthread_cond_wait(),pthread_cond_wait()是一个阻塞的函数,直到pthread_cond_signal()来唤醒它。唤醒了之后这段代码就执行完了一次,此后就从头再来,继续判断,然后阻塞等待 。

我不知道这么说你明白没有。


BTW:顺便说一下昨天的一个 问题:
其它线程也有可能先于它被唤醒,对count进行操作。[不确定,好像现在的系统里已经屏蔽掉了“惊群”现象] 

我刚才看了一下man pthread_cond_signal
DESCRIPTION
       These functions shall unblock threads blocked on a condition variable.

       The  pthread_cond_signal()  function  shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).

       If more than one thread is blocked on a condition variable, the scheduling policy shall determine the order  in  which  threads  are unblocked.  When  each  thread unblocked as a result of a pthread_cond_broadcast() or pthread_cond_signal() returns from its call to pthread_cond_wait() or pthread_cond_timedwait(), the thread shall  own  the  mutex  with  which  it  called  pthread_cond_wait()  or pthread_cond_timedwait(). The thread(s) that are unblocked shall contend for the mutex according to the scheduling policy (if appli cable), and as if each had called pthread_mutex_lock().

       The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread  calling  pthread_cond_broadcast() or pthread_cond_signal().

       The  pthread_cond_broadcast()  and pthread_cond_signal() functions shall have no effect if there are no threads currently blocked on cond.


红色标识就是所谓惊群现象。
蓝色标识就是说明多个线程被唤醒后调度的策略。

|



1:
1.当线程阻塞在cond_wait后,如果这时收到了cond_signal,它的状态即变为就绪态,等到CPU资源后就可以向下执行,并不是接收到signal后立即转为执行。 [理解OK]
其它线程也有可能先于它被唤醒,对count进行操作。[不确定,好像现在的系统里已经屏蔽掉了“惊群”现象]

2:
.关于阻塞在cond_wait的线程,接收到cond_signal并且分到CPU后的执行顺序:
        是在cond_wait中自动完成加锁及判断条件
那他是怎么知道判断条件的呢?你这里的判断条件是指什么?

|
如果cond_wait都还没来得及执行,他怎么自动加锁呢?如果先于它被调度的一个线程锁了count并对其操作,count值在cond_wait醒来时不就被改变了吗?

我感觉你好像搞混了,在cond_wait之前count_lock已经锁住了:

在line7,line9(开区间)之间,count_lock是被锁住了的,其他线程拿不到这把锁也就改不了count
在line9 pthread_cond_wait执行期间, count_lock被解锁了,其他线程可以改变count
line9 pthread_cond_wait返回后,count_lock继续被锁,其他线程拿不到锁改不了count

|
Linux 下我认为是这样的:
pthread_mutex_lock(&count_lock); // count_lock 锁住

pthread_cond_wait(&count_nonzero, &count_lock); // 如果没有收到信号线程进入阻塞队列,该线程对count_lock解锁(内部实现)并进入Sleep状态,当收到signal信号后,对count_lock加锁,然后继续向后执行

pthread_mutex_unlock(&count_lock); // 解锁

在RedHat 9.0下面是这样的。而且当调用signal时,如果此时对条件变量count_nonzero阻塞的队列是空的,发送的信号还会丢失。

|
PThreads Primer 一书中这样描述的:
                  ?
  lock-> cond -----> continue unlock
         ^ | 
         | |-------> unlock sleep lock -> |
         |                    ^           |
         ---------------------|-----------|
                               |
                                |
                                 |
lock-> cond = TRUE -> unlock ->wakeup -> continue

但我在RedHat 9.0 上测试了一下,感觉不像,不知道在其他平台上是什么样的,

大家可以在其他平台上测试 然后分享下结果。

|
pthread_cond_wait执行时,count_lock解锁,pthread_cond_wait返回前再自动加锁,所以描述1不可能,除非某处操作count前没有锁count_lock

    
 
 

您可能感兴趣的文章:

  • linux 下设置环境变量 使用了setenv 和putenv 在程序结束以后 发现变量又变回去了
  • 如何在若干个类中使用同样的变量?变量的值在一个类中赋予,在其它类中调用。
  • linux内核怎么定义汇编全局变量及在c文件中使用这个变量?有关0。11下的字符回显
  • 在shell中使用mail函数的时候如何使用变量
  • 在JBUILDER中如何使用全局变量,最好举一个例子。我也不知道在哪里定义全局变量?
  • 网卡驱动使用全局变量
  • 在ACC变成中要使用发ftp传送文件,但文件名不确定,请问怎么样在程序的FTP中使用字符串变量???
  • 请教:使用什么命令查看导出的环境变量?
  • gdb中使用set给变量赋值的问题
  • Makefile中的变量先使用后定义的问题
  • 条件编译可以使用全局变量吗?
  • 请问使用crontab是否必须设置环境变量?
  • 关于指针变量,struct 变量,指针使用的一些疑惑,望高手指教
  • 怎么样在JSP中使用PHP的变量呀??
  • 如何在Servlet中使用Application变量?
  • RADHAT下怎样使用PATH变量
  • 有没有方法可以使用脚本批量修改bash环境变量
  • 在线等,sed中可以使用变量吗?
  • [请问]如果在sed命令使用环境变量
  • awk程序中使用shell的变量
  • MySQL中使用case when 语句实现多条件查询的方法
  • 关于在shell中使用循环和条件判断的问题( 内详)
  • Python数组条件过滤filter函数使用示例
  • 在shell中使用数组需要什么特殊的条件马? 怎么在有的linux下能够用,在有的linux下就不能能使用?
  • 线程里互斥和条件变量一起使用的问题,有点迷惑.
  • MYSQL中有关SUM字段按条件统计使用IF函数(case)问题
  • 使用TSL命令实现进程同步和互斥来防止竞争条件!
  • 关于条件变量的使用
  • Thinkphp使用mongodb数据库实现多条件查询方法
  • CSS条件注释的使用详解教材
  • 不同版本IE使用不同css(css条件注释语句用法)
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • nginx Windows版相关问题及使用说明
  • gcc和cc得使用问题?能互相交换使用么?
  • php开源软件 iis7站长之家
  • 使用VWMARE安装linux的内存使用问题
  • 原来使用在这里:vmware中的redhat 8.0使用声卡的问题!!急
  • 几台机器做lvs,使用100M 网线连接,文件系统使用NFS共享,读写速度会出现问题吗?
  • ubuntu的问题。查看内存使用情况的问题
  • 菜鸟问题,小弟刚刚使用LINUX不久,不知道如何使用编程工具进行编译和运行!
  • 请教两个小问题:一个cgywin下使用vi的问题,另一个socket的问题
  • 弱智问题:我们怎么才知道要使用的方法需要实现什么接口才能使用这个方法呢?
  • 菜鸟问题 : 关于使用Flex的问题
  • 关于linux下QQ和代理服务器使用的问题(2个问题)
  • freebsd做前台 使用win2000做储存器问题问题(非高手免进)
  • 初学者问题(2):关于super的使用问题,请大家多多帮忙。
  • fedara13 初使用之问题
  • 关于windows下的gcc使用问题
  • 移动硬盘使用问题求解?百分相赠!!
  • 关于如何使用内核函数的问题
  • 我在使用j2sdkee1.3.1使用deploytool部署EJB时发现这样的问题
  • 急求,用户程序使用atomic的编译问题!!
  • 关于一个jbuilder使用的问题
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法


  • 站内导航:


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

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

    浙ICP备11055608号-3