实现多线程安全的队列 STL容器不是线程安全的,基于STL的 dequeue容器,利用上面所学的多线程知识, 来实现一个线程安全的双端队列。include include include ifndef NDEBUGelseendifusing Callable = std::function;templateclass SafeDequeue {public: SafeDequeue() = default; ~SafeDequeue() = default; SafeDequeue(const SafeDequeue&) = delete; SafeDequeue& operator=(const SafeDequeue&) = delete;private: using unique_lock = std::unique_lock;public: template void push_front(_Fun&& callback);//万能引用 template void push_back(_Fun&& callback);//万能引用 void pop_front(T& callback); void pop_back(T& callback); bool pop_front(T& callback, uint32_t timeout); bool pop_back(T& callback, uint32_t timeout); void swap(T& right); size_t size() const; bool empty() const; void clear();private: std::deque mDequeue; mutable std::mutex mMutex;//常成员函数不能改变类的成员变量的值,除非该成员变量为mutable std::condition_variable mCond;};include "SafeDequeue.h"templatetemplateinline void SafeDequeue::push_front(_Fun&& callback){ unique_lock lock(mMutex); mDequeue.emplace_front(std::forward(callback));//原地构造,完美转发 lock.unlock(); DEBUG_PRINT("push_front\n"); mCond.notify_one();}templatetemplateinline void SafeDequeue::push_back(_Fun&& callback){ unique_lock lock(mMutex); mDequeue.emplace_back(std::forward(callback));//原地构造,完美转发 lock.unlock(); DEBUG_PRINT("push_back\n"); mCond.notify_one();}templateinline void SafeDequeue::pop_front(T& callback){ unique_lock lock(mMutex); mCond.wait(lock, [this] { return !mDequeue.empty(); }); callback = std::move(mDequeue.front()); mDequeue.pop_front(); DEBUG_PRINT("pop_front\n");}templateinline bool SafeDequeue::pop_front(T& callback, uint32_t timeout){ unique_lock lock(mMutex); const bool result = mCond.wait_for(lock, std::chrono::milliseconds(timeout), [this] { return !mDequeue.empty(); }); if (result) { callback = std::move(mDequeue.front()); mDequeue.pop_front(); } DEBUG_PRINT("pop_front\n"); return result;}templateinline void SafeDequeue::pop_back(T& callback){ unique_lock lock(mMutex); mCond.wait(lock, [this] { return !mDequeue.empty(); }); callback = std::move(mDequeue.back()); DEBUG_PRINT("pop_back\n"); mDequeue.pop_back();}templateinline bool SafeDequeue::pop_back(T& callback, uint32_t timeout){ unique_lock lock(mMutex); const bool result = mCond.wait_for(lock, std::chrono::milliseconds(timeout), [this] { return !mDequeue.empty(); }); if (result) { callback = std::move(mDequeue.back()); mDequeue.pop_back(); } DEBUG_PRINT("pop_back\n"); return result;}templateinline void SafeDequeue::swap(T& right){ unique_lock lock1(mMutex, std::adopt_lock); unique_lock lock2(right.mMutex, std::adopt_lock); std::lock(lock1, lock2); mDequeue.swap(right.mDequeue); DEBUG_PRINT("swap\n");}templateinline size_t SafeDequeue::size() const{ std::unique_lock mlock(mMutex);//常成员函数不能改变类的成员变量的值,除非该成员变量为mutable DEBUG_PRINT("size\n"); return mDequeue.size();}templateinline bool SafeDequeue::empty() const{ std::unique_lock mlock(mMutex); DEBUG_PRINT("empty\n"); return mDequeue.empty();}templateinline void SafeDequeue::clear(){ std::unique_lock mlock(mMutex); DEBUG_PRINT("clear\n"); return mDequeue.clear();}