免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5310 | 回复: 11
打印 上一主题 下一主题

[C] 多线程的pthread_cond_wait后,记住再次检测条件 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-04 23:33 |只看该作者 |倒序浏览
一般来说,在多线程竞争一个资源的时候,会用到pthread_cond_wait,pthread_cond_signal机制,典型的做法就是在一个使用这个资源的线程(消费者)里面,判断资源如果不可用的话,则pthread_cond_wait,在另外一个线程(生产者)中判断如果资源可用的话,则发一个pthread_cond_signal或者pthread_cond_broadcast通知wait的线程。

但是有一个问题,就是在wait成功后,实际上此时的资源是否就一定可用呢?答案是否定的,如果存在两个线程同时使用这个资源的话,wait返回后,有可能资源已经被使用了。所以在这种情况下,判断资源是否可用,应该用如下模型:

while (resource==TRUE)        {           
    pthread_cond_wait( &COND, &MUTEX);         
}

这里用了while,而不是用if,原因就是上面提到的。当然,如果在应用中,只有一个消费者,就可以直接用if了。


要搞清楚这个问题背后的问题,就需要知道pthread_cond_wait的实际过程。
当发起一个pthread_cond_wait之后,分解后,实际上是两个动作:
    1、解锁
    2、等待
当收到一个解除等待的信号(pthread_cond_signal或者pthread_cond_broad_cast)之后,pthread_cond_wait马上需要做的动作是:
    3、上锁

了解这个原理后,假设出现如下场景:如果消费者A的wait在收到解除信号后,去上锁,但是这个时候,被消费者B先上锁,把资源使用掉了,然后解锁,然后消费者A上锁成功,wait返回,而此时资源已经不可用了,所以消费者A必须在判断一下资源的可用性。

论坛徽章:
0
2 [报告]
发表于 2008-06-05 09:16 |只看该作者
UNP上说了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2008-06-05 09:17 |只看该作者
man 里边也说了.

论坛徽章:
0
4 [报告]
发表于 2008-06-05 09:30 |只看该作者
原帖由 towerjt 于 2008-6-4 23:33 发表
了解这个原理后,假设出现如下场景:如果消费者A的wait在收到解除信号后,去上锁,但是这个时候,被消费者B先上锁,把资源使用掉了,然后解锁,然后消费者A上锁成功,wait返回,而此时资源已经不可用了,所以消费者A必须在判断一下资源的可用性。


可是pthread_cond_signal只会唤醒一个啊,(不同于pthread_cond_broadcast)
A被唤醒的同时,B应该等待在pthread_cond_wait中的,不存在LZ说的情况。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2008-06-05 09:53 |只看该作者

回复 #4 芙蓉 的帖子

man pthread_cond_signal

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).

论坛徽章:
0
6 [报告]
发表于 2008-06-05 11:40 |只看该作者
原帖由 cookis 于 2008-6-5 09:53 发表
man pthread_cond_signal

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 ar ...


收到,謝謝!
倒是提醒了我,以前代碼裏有很多沒有檢查的地方。
多放一次檢查也沒壞處的

论坛徽章:
0
7 [报告]
发表于 2009-11-25 17:26 |只看该作者

回复 #1 towerjt 的帖子

多说有益

论坛徽章:
0
8 [报告]
发表于 2009-11-25 18:05 |只看该作者
最关键的问题,signal/wait只是通知机制,本身不代表资源情况,当发signal时没有人在wait,那么这个signal就会丢失,
后来再wait的就等不到signal了,而在多线程中,发signal和wait的顺序往往不能保证的,因此比较完善的流程应该是:

发送者:
pthread_mutex_lock()
resource++
pthread_cond_signal()
pthread_mutex_unlock()


等待者:
pthread_mutex_lock()
while( 1 ) {
   if( resource > 0 ) {
       resource --;
       break;
  }
   pthread_cond_wait()
}
pthread_mutex_unlock()

论坛徽章:
0
9 [报告]
发表于 2009-11-25 18:10 |只看该作者
不错  mark!

论坛徽章:
0
10 [报告]
发表于 2012-10-10 15:07 |只看该作者
感谢楼主~~  回复 1# towerjt


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP