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 : 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 }
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 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。