首页 > 代码库 > Linux组件封装(二) 条件变量Condition的封装

Linux组件封装(二) 条件变量Condition的封装

声明代码如下:

 1 #ifndef CONDITION_H 2 #define CONDITION_H 3  4 #include <pthread.h> 5 #include "noncopyable.h" 6  7 class MutexLock; 8  9 10 class Condition : NonCopyable11 {12 public:13     Condition(MutexLock &mutex);14     ~Condition();15 16     void wait();17     void notify();18     void notifyAll();19 private:20     pthread_cond_t _cond;21     MutexLock &_mutex;22 };23 24 #endif

需要注意:

1.wait必须在加锁条件下调用

2.notify一次唤醒一个线程,通常用来通知资源可用

3.notifyAll一次通知多个线程,通常用来通知状态的变化。滥用broadcast会导致"惊群"问题。

 

使用wait必须采用while判断,原因在于:

1.如果采用if,最多判断一次

2.线程A等待数据,阻塞在full上,那么当另一个线程放入产品时,通知A去拿数据,此时另一个线程B抢到锁,直接进入临界区,取走资源。A重新抢到锁,(因为采用的是if,所以不会判断第二次)进去临界区时,已经没有资源。

3.防止broadcast的干扰,如果获得一个资源,使用broadcast会唤醒所有等待的线程,那么多个线程被唤醒,但最终只有一个能拿到资源,这就是所谓的“惊群效应”。

 

cpp代码实现如下:

 1 #include "Condition.h" 2 #include "MutexLock.h" 3 #include <assert.h> 4  5 Condition::Condition(MutexLock &mutex) 6     :_mutex(mutex) 7 { 8     TINY_CHECK(!pthread_cond_init(&_cond, NULL)); 9 }10 11 Condition::~Condition()12 {13     TINY_CHECK(!pthread_cond_destroy(&_cond));14 }15 16 void Condition::wait()17 {18     assert(_mutex.isLocked());19     TINY_CHECK(!pthread_cond_wait(&_cond, _mutex.getMutexPtr()));20 }21 22 void Condition::notify()23 {24     TINY_CHECK(!pthread_cond_signal(&_cond));25 }26 27 void Condition::notifyAll()28 {29     TINY_CHECK(!pthread_cond_broadcast(&_cond));30 }

 

Linux组件封装(二) 条件变量Condition的封装