线程、进程通信---cond=>条件变量

来源:互联网 发布:手机淘宝怎么搜图片 编辑:程序博客网 时间:2024/06/03 18:31

      前一节中我们讲述了如何使用互斥锁来实现线程间数据的共享和通信,互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。

而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来

阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应
的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将
重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线程间的同步。

条件变量的结构为 pthread_cond_t,

函数 pthread_cond_init()被用来初始化一个条件变量。它的原型为:

extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t  *__cond_attr));
其中 cond 是一个指向结构 pthread_cond_t 的指针,cond_attr 是一个指向结构 pthread_condattr_t 的指针。结构 pthread_condattr_t 是条
件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进
程内可用还是进程间可用,默认值 PTHREAD_PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。

注意初始化条件变量只有未被使用时才能重新初始化或被释放。释放一个条件变量的函数为

pthread_cond_ destroy(pthread_cond_t cond)。

函数 pthread_cond_wait()使线程阻塞在一个条件变量上。它的
函数原型为:
extern int pthread_cond_wait __P ((pthread_cond_t*__cond,pthread_mutex_t *__mutex));

线程解开 mutex 指向的锁并被条件变量 cond 阻塞。

线程可以被函数 pthread_cond_signal 和函数 pthread_cond_broadcast 唤醒,

但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件
还需用户给出,例如一个变量是否为 0 等等,这一点我们从后面的例子中可以看到。线程被唤醒后,它将重新检查判断条件是否满足,如
果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。这个过程一般用 while 语句实现。

另一个用来阻塞线程的函数是

pthread_cond_timedwait(),它的原型为:

extern int pthread_cond_timedwait __P ((pthread_cond_t*__cond,pthread_mutex_t *__mutex, __const struct timespec*__abstime));
它比函数 pthread_cond_wait()多了一个时间参数,经历 abstime 段时间后,即使条件变量不满足,阻塞也被解除。
函数 pthread_cond_signal()的原型为:extern int pthread_cond_signal __P ((pthread_cond_t*__cond));
它用来释放被阻塞在条件变量 cond 上的一个线程。多个线程阻
塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略所决定的。要注意的是,必须用保护条件变量的互斥锁来保护这个函数,否
则条件满足信号又可能在测试条件和调用 pthread_cond_wait 函数之
间被发出,从而造成无限制的等待。下面是使用函数
pthread_cond_wait()和函数 pthread_cond_signal()的一个简单的

pthread_mutex_t count_lock;pthread_cond_t count_nonzero;unsigned count;decrement_count() {pthread_mutex_lock (&count_lock);while(count==0)pthread_cond_wait( &count_nonzero, &count_lock);count=count -1;pthread_mutex_unlock (&count_lock);}increment_count(){pthread_mutex_lock(&count_lock);if(count==0)pthread_cond_signal(&count_nonzero);count=count+1;pthread_mutex_unlock(&count_lock);}

count 值为 0 时,decrement 函数在 pthread_cond_wait 处被阻塞,并打开互斥锁count_lock。此时,当调用到函数
increment_count 时,pthread_cond_signal()函数改变条件变量,告知 decrement_count()停止阻塞。可以试着让两个线程分别运行这两个函数,看看会出现什么样的结果。
函数 pthread_cond_broadcast(pthread_cond_t *cond)用来唤醒所有被阻塞在条件变量 cond 上的线程。这些线程被唤醒后将再次竞争相应的互斥锁,所以必须小心使用这个函数。


原创粉丝点击