djsxut 发表于 2011-12-13 13:06

pthread_cond_wait里面的mutex作用APUE里面也有写,就是安全的把该线程安全加入到等待条件发生的队列上。

hbmhalley 发表于 2011-12-13 13:33

回复 11# djsxut


    明白了. 谢谢

bqq402 发表于 2011-12-13 15:50

啊是啊我的理解和你完全一样 但整个过程中和mutex有半毛钱关系么?? 晕死我了 ..

djsxut 发表于 2011-12-14 11:04

条件变量都用互斥锁进行保护,条件变量状态的改变都应该先锁住互斥锁,pthread_cond_wait需要传入一个已经加锁的互斥锁,该函数把调用线程加入等待条件的调用列表中,然后释放互斥锁,这是一个原子操作。可以消除条件发生和线程睡眠等待条件发生间的时间间隙。比如说如果没有互斥锁,那么线程先判断条件是否发生,如果没有发生,让线程睡眠继续等待。如果在判断是否发生和线程睡眠这个间隙条件发生了,这就会有问题。

hbmhalley 发表于 2011-12-14 12:12

回复 14# djsxut


    就是说 为了避免 因 条件判断语句 与 其后的正文或wait语句 之间的间隙而产生的漏判或误判 , 所以用一个mutex来保证: 对于某个cond的 包括(判断,修改)在内的任何有关操作 某一时刻只有一个线程在访问
    也就是说 条件变量本身就是一个竞争资源,这个资源的作用是对其后程序正文的执行权,于是用一个锁来保护
    可以这样理解么?

hbmhalley 发表于 2011-12-14 12:17

回复 14# djsxut


    但是 如果用mutex消除了**与**之间的间隙,那么broadcast是什么作用?任意一个wait返回之前都会把mutex给锁住啊

djsxut 发表于 2011-12-14 12:37

回复 16# hbmhalley


    嗯,差不多这样,我认为就是按照一定的规程来进行操作,所以这种机制才生效。broadcast唤醒所有阻塞在该条件变量上的线程,然后按照一定的调度机制,线程竞争,就好像这些线程一起调用pthread_mutex_lock一样,所以最终也只有一个能够获得锁资源然后返回。不能获得锁的继续等待。

hbmhalley 发表于 2011-12-14 14:35

回复 17# djsxut


    哦 ..
    刚才不理解 既然有mutex限制cond,那么broadcast也只能唤醒一个阻塞的线程,和signal有什么区别?
    现在好像理解了,signal唤醒cond队列中的一个线程,但broadcast唤醒队列中所有线程,只不过都因为阻塞在mutex上而没有工作而已,线程之后的走向就决定在mutex上而与cond无关了

djsxut 发表于 2011-12-14 18:10

回复 18# hbmhalley


    嗯。还有一点小区别,signal函数是唤醒至少一个线程,这是man pthread_cond_signal里说的。可以自己去man一下,然后去看看APUE。

madbunny 发表于 2016-04-28 18:32

因为没有锁,只有条件变量是保证不了资源的互斥访问的。

你看wait函数的用法,它阻塞结束之后就不管剩下的代码了。不像mutex前后包含一下,保证中间的代码可以安全的访问被保护的资源。

但是为什么一定要传进去一个mutex参数呢?因为实际上wait函数偷偷地unlock了穿进去的锁。
需要用到wait函数的都是消费者。条件变量需要保证生产者优先访问资源,生产者访问资源又必须要get锁,所以wait函数其实是把得到的锁unlock了。等到退出之前再重新尝试lock。
这样才可以保证资源可用的时候消费者可以安全访问,资源不可用的时候也不会被消费者锁住,生产者访问不到。
页: 1 [2]
查看完整版本: 条件变量为什么要用互斥锁来保护?