这篇文章只讲述下条件变量pthread_cond_t的作用和理解,函数已在别的文章中给出。
互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。
(1)等待机制
使用时,条件变量被用来阻塞一个线程:
当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化;
一旦其它的某个线程改变了条件变量,系统将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件(检测条件必须是全局变量,所有需要同步的线程能够访问)是否满足。
个人比较喜欢用布尔型变量来做测试条件,如:bool bIsLocked=false;
(2)条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为真等等。
线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用while语句实现。
while(bLock==true) pthread_cond_wait(&g_cond, &g_mutex);
(3)多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略所决定的。
(4)必须用保护条件变量的互斥锁来保护唤醒函数pthread_cond_signal(),否则条件满足时,信号又可能在测试条件和调用pthread_cond_wait函数之间被发出,从而造成无限制的等待。
即pthread_cond_signal()需要放在pthread_mutex_lock()和pthread_mutex_unlock()之间。
(5)条件变量的等待和唤醒是一对一的关系,有点类似于开关。
(6)pthread_cond_wait()函数的说明:该函数在条件满足之后,立刻返回,然后去获取互斥锁,以执行接下来的操作。
注意:pthread_cond_wait()函数条件满足之后重新获取互斥锁的过程比较慢,所以必须用while(判断条件)判断,在此期间是否有别的线程已经使得条件不满足。
下面是自己写的一个例子:
全局变量:
//互池锁 pthread_mutex_t g_mutex; //条件变量 pthread_cond_t g_cond; //标识变量 bool bLock; unsigned int count;线程的回调函数:
void * increment_count(void * arg) { pthread_mutex_lock(&g_mutex); while(bLock) pthread_cond_wait(&g_cond, &g_mutex); bLock=1; count+=1; printf("increment thread: count+=1\n"); pthread_cond_signal(&g_cond); pthread_mutex_unlock(&g_mutex); bLock=0; }