Linux组件封装(四) Buffer的封装

这里,我们需要将缓冲区封装起来,然后让缓冲区与线程想连接,所以我们需要一个相应的接口。

在Buffer中,我们需要想对应的一把锁与两个条件变量。

当满足队列为空时,消费者等待,反之,生产者等待。

Buffer的声明如下:

 1 #ifndef BUFFER_H
 2 #define BUFFER_H
 3 
 4 #include "NonCopyable.h"
 5 #include "MutexLock.h"
 6 #include "Condition.h"
 7 #include <queue>
 8 
 9 
10 class Buffer : private NonCopyable
11 {
12 public:
13 
14     Buffer(size_t queueSize);
15 
16     void push(int val);
17     int pop();
18 
19     bool empty() const;
20     size_t size() const;
21 
22 private:
23 
24     mutable MutexLock _mutex;
25     Condition _full;
26     Condition _empty;
27     size_t _queueSize;
28     std::queue<int> _queue;
29 };
30 
31 
32 #endif  /*BUFFER_H*/
View Code

在这里,我们引用MutexLockGuard来解决忘记解锁的问题,当我们定义一个该类的对象时,·自动上锁,
当该对象销毁时,自动解锁。

当然,有一种使用方式是错误的,例如:

size_t Buffer::size() const
{
    MutexLockGuard(mutex_);
    return queue_.size();
}

这段代码的加锁周期仅在那一行有效,所以该种方法是错误的,所以,我们定义一个宏(在Mutex.h文件中可找到):

#define MutexLockGuard(m) "Error"

这样当错误使用时,会导致编译错误,使我们早些发现问题。

cpp实现代码如下:

 1 #include "Buffer.h"
 2 #include "Thread.h"
 3 using namespace std;
 4 
 5 Buffer::Buffer(size_t queueSize)
 6     :_full(_mutex),
 7      _empty(_mutex),
 8      _queueSize(queueSize)
 9 {
10 
11 }
12 
13 bool Buffer::empty() const
14 {
15     MutexLockGuard lock(_mutex);
16     return _queue.empty();
17 }
18 
19 size_t Buffer::size() const
20 {
21     MutexLockGuard lock(_mutex);
22     return _queue.size();
23 }
24 
25 void Buffer::push(int val)
26 {
27     {
28         MutexLockGuard lock(_mutex);
29         while(_queue.size() > _queueSize)
30             _empty.wait();
31         _queue.push(val);
32     }
33     _full.notify();
34 }
35 
36 int Buffer::pop()
37 {
38     int tmp = 0;
39     {
40         MutexLockGuard lock(_mutex);
41         while(_queue.empty())
42             _full.wait();
43         tmp = _queue.front();
44         _queue.pop();
45     }
46     _empty.notify();
47     return tmp;
48 }
View Code
原文地址:https://www.cnblogs.com/gjn135120/p/4009428.html