01.webserver源码阅读--BlockQueue
00.webserver源码阅读--buffer - DavidJIAN - 博客园 (cnblogs.com)
blockQueue
这是一个日志输出的缓冲区的类。其实就是一个队列加上一些同步机制,而队列中的元素可以简单为日志输出任务。采用的
生产者-消费者模式。
成员变量
-
m_deq
- deque。本项目用于存储deque< string >
-
m_capacity
- 阻塞队列的(最大)容量
-
m_mutex
- 用于对m_deq的锁(互斥变量)
-
shutdown
- 缓冲区关闭标志
-
cond_consumer和cond_producer
- 用于生产者-消费者的同步的条件变量
成员函数
-
构造函数
- 传入队列容量,并初始化
-
析构函数
- 调用Close函数
-
empty() 和 full()
- 检查是否为空或满
-
close()
- 上锁,清空队列
{ std::lock_guard<std::mutex> locker(m_mutex); m_deq.clear(); shutdown = true; }lock_gaurd主要是对mutex的封装,RAII。构造对象时上锁,析构时解锁。上面用block主要是减少临界区范围。参考链接:(219条消息) C++11多线程之std::lock_guard_执假以为真的博客-CSDN博客_c++ lock_guard
- cond_xxx.notify_all()
-
size() 和 capacity()
- size返回队列当前元素个数
- capacity返回最大容量
-
front() 和 back()
- 取队列元素以供消费:用m_mutex上锁,调用m_deq的front和back
-
push_back() 和 push_front()
- 两者基本一样,主要是放前还是放后
- 上锁,当没有位置放时,cond_producer.wait
- 注意1:cond需要在mutex上锁后再用
- 注意2:cond需要放在while循环里wait。(219条消息) 条件变量—虚假唤醒(放到while循环的原因)_平平无奇的小垃圾的博客-CSDN博客
template<class T> void web::blockQueue<T>::push_front(const T &item) { std::unique_lock<std::mutex> locker(m_mutex); while (m_deq.size() >= m_capacity) { cond_producer.wait(locker); } m_deq.push_front(item); cond_consumer.notify_one(); } -
pop()
- 有两个版本一个是有超时时间的
- 无超时时间的版本:若空,则cond_consumer.wait生产者等待,放入后cond_producer.notify_one唤醒消费者.
- 有超时时间的版本:与无超时时间的版本一样。只不过cond_consumer用的是wait_for函数。其中超时时间用std::chrono::seconds(timeout)指定。关于std::chrono:C++11 std::chrono库详解 - mjwk - 博客园 (cnblogs.com)
-
flush()
- 通知消费者,cond_consumer.notify_one()

浙公网安备 33010602011771号