• 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
  • 相关阅读:
    Go HTTP Client 持久连接
    监控指标go.mongodb.org/mongodriver的prometheus
    Mybatis拦截器自定义prometheus监控指标
    Springboot开启prometheus监控指标获取HTTP请求的吞吐时延等
    Golang 环境变量详解
    Navicat
    springboot单元测试常用写法
    golang枚举值定义
    java 实现 类似 reids nx锁 , 模拟秒杀操作
    分布式幂等1(基于一次性token) 自定义接口幂等(注解) @AvoidResubmit(isLoc = false)
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4009428.html
Copyright © 2020-2023  润新知