欢迎来到代码驿站!

C代码

当前位置:首页 > 软件编程 > C代码

C++线程安全的队列你了解嘛

时间:2022-08-04 10:03:50|栏目: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++图解单向链表类模板和iterator迭代器类模版详解

栏    目:C代码

下一篇:C语言数据结构中二分查找递归非递归实现并分析

本文标题:C++线程安全的队列你了解嘛

本文地址:http://www.codeinn.net/misctech/209851.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有