Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76365
  • 博文数量: 47
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-12 18:04
文章分类

全部博文(47)

文章存档

2010年(7)

2009年(40)

我的朋友

分类: LINUX

2009-07-08 16:59:21

pthreads条件变量小结

部分内容参看了网上的资料

 

条件变量给多线程提供了一种通知唤醒的机制。但是关于条件变量的使用,有一些很纠结的问题。

 

关于条件的检测

  1. 在锁住互斥量之后和在等待条件变量之前,需要测试条件变量。如果发送了信号,而没有进程在信号上等待,就不会发生任何事情
  2. 当等待线程醒来时,要测试条件变量。应该总在循环中来实现,以防止假唤醒。

条件检测有一些惯用的pthread_cond_wait()和pthread_cond_signal()的写法:

在等待端:

Cpp代码
  1. pthread_mutex_lock(&m);   
  2. while( condition_is_false )   
  3.     pthread_cond_wait(&cond, &m);//自动释放锁   
  4. pthread_mutex_unlock(&m);  

 在发信号端:

Cpp代码
  1. pthread_mutex_lock(&m);//pthread_cond_wait已自动释放锁   
  2. ......   
  3. pthread_cond_signal(&v);   
  4. pthread_mutex_unlock(&m);//释放锁,使得pthread_cond_wait可以自动再次获得锁  

 

调用pthread_cond_wait()之前必须获得锁。pthread_cond_wait()其实对互斥量做了解锁操作 。首先,将解锁与挂起线程做为原子操作执行,这样pthread_cond_signal()即可获互斥量。当pthread_cond_wait()返回时,又会自动加锁,所以其效果相当于持有的锁的状态没有改变。

 

被pthread_cond_wait()阻塞的线程可以被pthread_cond_signal函数,pthread_cond_broadcast函数唤醒,也可能在被信号中断后被唤醒(造成假唤醒)。pthread_cond_wait()函数的返回并不意味着条件的值一定发生了变化(有可能是假唤醒),也可能是函数出错返回,因此必须重新检查条件的值,比如用while()来确认。 pthread_cond_wait()函数返回时,相应的互斥锁将被当前线程锁定。

 

必须在互斥锁的保护下使用相应的条件变量。否则对条件变量的通知有可能发生在等待条件变量之前,从而造成死锁;导致死锁的最常见错误是自死锁或递归死锁。在自死锁或递归死锁中,线程尝试获取已被其持有的锁。递归死锁是在编程时很容易犯的错误。另外,如果没有线程被阻塞在条件变量上,那么调用 pthread_cond_signal()将没有作用。

 

阅读(546) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~