声明代码如下:
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 : NonCopyable 11 { 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 _mutex.restoreMutexStatus(); 21 } 22 23 void Condition::notify() 24 { 25 TINY_CHECK(!pthread_cond_signal(&_cond)); 26 } 27 28 void Condition::notifyAll() 29 { 30 TINY_CHECK(!pthread_cond_broadcast(&_cond)); 31 }