分类: LINUX
2009-07-08 16:59:21
部分内容参看了网上的资料
条件变量给多线程提供了一种通知唤醒的机制。但是关于条件变量的使用,有一些很纠结的问题。
关于条件的检测
条件检测有一些惯用的pthread_cond_wait()和pthread_cond_signal()的写法:
在等待端:
pthread_mutex_lock(&m); while( condition_is_false ) pthread_cond_wait(&cond, &m);//自动释放锁 pthread_mutex_unlock(&m);
在发信号端:
pthread_mutex_lock(&m);//pthread_cond_wait已自动释放锁 ...... pthread_cond_signal(&v); 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()将没有作用。