muduo原始碼解析17-(bounded)blockingqueue類
阿新 • • 發佈:2020-08-26
blockingqueue和boundedblockingqueue
作用:
無邊界blockingqueue:
實現了一個有鎖的dequeue雙端佇列
保證put,take,size操作都具有原子性
內部使用互斥鎖mutexlock,再使用一個條件變數用於判斷佇列是否為空
有邊界boundedblockingqueue:
實現了一個有邊界的雙端佇列,實現執行緒安全,對常用的操作加鎖,實現原子性
內部使用boost::circular_buffer來儲存資料
兩個類都比較簡單
blockingqueue:
/* 實現了一個有鎖的dequeue雙端佇列 保證put,take,size操作都具有原子性 內部使用互斥鎖mutexlock,再使用一個條件變數用於判斷佇列是否為空*/ #ifndef BLOCKINGQUEUE_H #define BLOCKINGQUEUE_H #include"base/condition.h" #include"base/mutex.h" #include<deque> #include<assert.h> namespace mymuduo { template <typename T> class blockingqueue:noncopyable { public: blockingqueue():m_mutex(),m_notEmpty(m_mutex),m_queue() { }//隊尾新增元素 void put(const T& x) { mutexlockguard mlg(m_mutex); m_queue.push_back(x); m_notEmpty.notify(); } void put(T&& x) { mutexlockguard mlg(m_mutex); //std::move把左值轉化成右值引用 m_queue.push_back(std::move(x)); m_notEmpty.notify(); }//隊頭取出元素 T take() { mutexlockguard mlg(m_mutex); while(m_queue.empty()) m_notEmpty.wait(); assert(!m_queue.empty()); T val=std::move(m_queue.front()); m_queue.pop_front(); return val; } size_t size() const { mutexlockguard mlg(m_mutex); return m_queue.size(); } private: //mutable修飾的成員變數可以在常成員函式中修改 mutable mutexlock m_mutex; condition m_notEmpty; std::deque<T> m_queue; }; } #endif // BLOCKINGQUEUE_H
boundedblockingqueue:
/* 實現了一個有邊界的佇列,實現執行緒安全,對常用的操作加鎖,實現原子性 內部使用boost::circular_buffer來儲存資料 */ #ifndef BOUNDEDBLOCKINGQUEUE_H #define BOUNDEDBLOCKINGQUEUE_H #include"base/condition.h" #include"base/mutex.h" #include<boost/circular_buffer.hpp> #include<assert.h> namespace mymuduo { template <typename T> class boundedblockingqueue:noncopyable { public: explicit boundedblockingqueue(int maxSize) :m_mutex(),m_notEmpty(m_mutex),m_notFull(m_mutex),m_queue(maxSize) { } //新增元素 void put(const T& x) { mutexlockguard mlg(m_mutex); while(m_queue.full()) m_notFull.wait(); assert(!m_queue.full()); m_queue.push_back(x); m_notEmpty.notify(); } void put(const T&& x) { mutexlockguard mlg(m_mutex); while(m_queue.full()) m_notFull.wait(); assert(!m_queue.full()); m_queue.push_back(std::move(x)); m_notEmpty.notify(); } //取出元素 T take() { mutexlockguard mlg(m_mutex); while(m_queue.empty()) m_notEmpty.wait(); assert(!m_queue.empty()); T val=std::move(m_queue.front()); m_queue.pop_front(); m_notFull.notify(); return val; } //返回佇列各種狀態... bool empty() const { mutexlockguard mlg(m_mutex); return m_queue.empty(); } bool full() const { mutexlockguard mlg(m_mutex); return m_queue.full(); } size_t size() const { mutexlockguard mlg(m_mutex); return m_queue.size(); } size_t capacity() const { mutexlockguard mlg(m_mutex); return m_queue.capacity(); } private: mutable mutexlock m_mutex; condition m_notEmpty; condition m_notFull; boost::circular_buffer<T> m_queue; }; }//namespace mymuduo #endif // BOUNDEDBLOCKINGQUEUE_H
兩個類都比較簡單,在常用的操作上加鎖實現執行緒安全,這裡不再測試了。