您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
这篇文章将为大家详细讲解有关C++线程安全的队列是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
#include<queue> #include<mutex> #include<condition_variable> #include<optional> #include<cassert> #include<thread> template<typename T,typename Container = std::queue<T>> class Queue //无界队列 { public: Queue() = default; ~Queue() = default; //禁止拷贝和移动,编译器会自动delete /*Queue(const Queue&) = delete; Queue(Queue&&) = delete; Queue& operator=(const Queue&) = delete; Queue& operator=(Queue&&) = delete;*/ void push(const T& val) { emplace(val); } void push(T&& val) { emplace(std::move(val)); } template<typename...Args> void emplace(Args&&...args) { std::lock_guard lk{ mtx_ }; q_.push(std::forward<Args>(args)...); cv_.notify_one(); } T pop()//阻塞 { std::unique_lock lk{ mtx_ }; cv_.wait(lk, [this] {return !q_.empty(); });//如果队列不为空就继续执行,否则阻塞 assert(!q_.empty()); T ret{ std::move_if_noexcept(q_.front()) }; q_.pop(); return ret; } std::optional<T> try_pop()//非阻塞 { std::unique_lock lk{ mtx_ }; if (q_.empty())return {}; std::optional<T> ret{ std::move_if_noexcept(q_.front()) }; q_.pop(); return ret; } bool empty()const { std::lock_guard lk{ mtx_ }; return q_.empty(); } private: Container q_; mutable std::mutex mtx_; std::condition_variable cv_; }; #include<iostream> int main() { Queue<int>q; std::thread t1( [&] { for (int i = 0; i < 100; ++i) { q.push(i); } }); std::thread t2( [&] { for (int i = 0; i < 100; ++i) { //std::cout<<q.pop()<<" "; if (auto ret = q.try_pop()) { std::cout << *ret<<" "; } } }); t1.join(); t2.join(); return 0; }
#include<mutex> #include<condition_variable> #include<boost/circular_buffer.hpp> #include<optional> template<typename T> class Queue { public: Queue(size_t capacity) :q_{ capacity }{} template<typename T> void push(T&& val)//阻塞 { std::unique_lock lk{ mtx_ }; not_full_.wait(lk, [this] {return !q_.full(); }); assert(!q_.full()); q_.push_back(std::move(std::forward<T>(val))); not_empty_.notify_one(); } template<typename T> bool try_push(T&& val)//非阻塞 { std::lock_guard lk{ mtx_ }; if (q_.full())return false; q_.push_back(std::forward<T>(val)); not_empty_.notify_one(); return true; } T pop()//阻塞 { std::unique_lock lk{ mtx_ }; not_empty_.wait(lk, [this] {return !q_.empty(); }); asert(!q_.empty()); T ret{ std::move_if_noexcept(q_.front()) }; q_.pop_front(); not_full_.notify_one(); return ret; } std::optional<T> try_pop()//非阻塞 { std::lock_guard lk{ mtx_ }; if (q_.empty())return {}; std::optional<T> ret{ std::move_if_noexcept(q_.front()) }; q_.pop_front(); not_full_.notify_one(); return ret; } private: boost::circular_buffer<T>q_; std::mutex mtx_; std::condition_variable not_full_; std::condition_variable not_empty_; }; #include<iostream> int main() { Queue<int>q(10); std::thread t1( [&] { for (int i = 0; i < 100; ++i) { q.push(i); } }); std::thread t2( [&] { for (int i = 0; i < 100; ++i) { //std::cout<<q.pop()<<" "; if (auto ret = q.try_pop()) { std::cout << *ret << " "; } } }); t1.join(); t2.join(); return 0; }
关于“C++线程安全的队列是什么”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。