Algorithm: 并发queue.

#include <utility>
#include <queue>
#include <mutex>
#include <memory>
#include <iostream>
#include <condition_variable>



template<typename T>
class Node {
public:
	Node() = default;
	~Node() = default;
	Node(const Node<T>& other) = delete;
	Node<T>& operator=(const Node<T>& other) = delete;

	Node(std::shared_ptr<T> data_, std::unique_ptr<Node<T>>&& next_ = nullptr)
		:data{ data_ },
		next{ std::move(next) }
	{
		//
	}

	Node(Node<T>&& other)
		:data{ std::move(other.data) },
		next{ std::move(other.next) }
	{
		//move-constructor.
	}


	Node<T>& operator=(Node<T>&& other)
	{
		this->data = std::move(other.data);
		this->next = std::move(other.next);
		(other.next).reset(nullptr);

		return *this;
	}


	std::shared_ptr<T> data{ nullptr };
	std::unique_ptr<Node<T>> next{ nullptr };
};


//先进先出(FIFO)
template<typename T>
class Queue {
public:


	//注意在默认构造函数的情况下:
	//创建了一个 empty的 node. 此时首尾都指向这个node.
	Queue()
		:head{ new Node<T>{} },
		tail{ head.get() }
	{
		//default constructor.
	}

	template<typename ...Types>
	Queue(Types&&... args);

	Queue(const Queue<T>&) = delete;
	Queue<T>& operator=(const Queue<T>&) = delete;

	void push(const T& value);
	void push(T&& value);
	bool try_pop(T& value);
	std::shared_ptr<T> try_pop();
	bool wait_pop(T& value);
	std::shared_ptr<T> wait_pop();

	bool empty();


private:

	//用于构造函数.
	template<typename Ty, typename ...Types>
	void initialList(Ty&& value, Types&&... args);

	template<typename Ty>
	void initialList(Ty&& value);

	inline Node<T>* getTail()
	{
		std::lock_guard<std::mutex> lock(this->tailM);
		return (this->tail);
	}

	mutable std::mutex headM{};
	mutable std::mutex tailM{};
	mutable std::condition_variable conVar{};
	
	std::unique_ptr<Node<T>> head{nullptr}; //队列头部.
	Node<T>* tail{}; //队列尾部.
};

template<typename T>
template<typename ...Types>
Queue<T>::Queue(Types&&... args)
	:head{ new Node<T>{} },
	tail{head.get()}
{
	std::lock(this->headM, this->tailM);
	std::lock_guard<std::mutex>(this->headM, std::adopt_lock);
	std::lock_guard<std::mutex>(this->tailM, std::adopt_lock);

	this->initialList(std::forward<Types>(args)...);
}

template<typename T>
template<typename Ty>
void Queue<T>::initialList(Ty&& value)
{
	std::shared_ptr<T> nodeData{ std::make_shared<T>(std::forward<Ty>(value)) };
	std::unique_ptr<Node<T>> node{ new Node<T>{} };

	(this->tail)->data = nodeData;
	Node<T>* newTail = node.get();
	(this->tail)->next = std::move(node);
	(this->tail) = newTail;
	newTail = nullptr;
}

template<typename T>
template<typename Ty, typename ...Types>
void Queue<T>::initialList(Ty&& value, Types&&... args)
{
	//向queue中插入数据.
	this->initialList(std::forward<Ty>(value));
	this->initialList(std::forward<Types>(args)...);
}

//删除顶部元素并把被删除的值保存到value中.
template<typename T>
bool Queue<T>::try_pop(T& value)
{
	std::lock(this->headM, this->tailM);
	std::lock_guard<std::mutex> lockOne{ this->headM, std::adopt_lock };

	if ((this->head).get() == this->getTail()) {
		return false;
	}

	std::unique_ptr<Node<T>> oldHead{ std::move(this->head) };
	value = std::move(*(oldHead->data));
	this->head = std::move(oldHead->next);
	return true;


	return oldHead;
}

//删除顶部元素并返回被删除的值.
template<typename T>
std::shared_ptr<T> Queue<T>::try_pop()
{
	std::lock(this->headM);
	std::lock_guard<std::mutex> lockOne(this->headM, std::adopt_lock);

	if ((this->head).get() == this->getTail());

	std::unique_ptr<Node<T>> oldHead{ std::move(this->head) };
	std::shared_ptr<T> nodeData{ std::move(oldHead->data) };
	this->head = std::move(oldHead->next);

	return nodeData;
}

template<typename T>
bool Queue<T>::empty()
{
	std::lock_guard<std::mutex>(this->headM);

	if ((this->head).get() == (this->getTail())) {
		return true;
	}
	return false;
}

template<typename T>
bool Queue<T>::wait_pop(T& value)
{
	std::shared_ptr<T> ptrValue{ this->wait_pop() };
	if (ptrValue == nullptr) {
		return false;

	} else {
		value = std::move(*ptrValue);
		return true;

	}
}

template<typename T>
void Queue<T>::push(const T& value)
{
	std::shared_ptr<T> nodeData{ std::make_shared<T>(value) };
	std::unique_ptr<Node<T>> node{ new Node<T>{} };

	{
		std::lock_guard<std::mutex> lockGuard(this->tailM);
		(this->tail)->data = nodeData;
		Node<T>* newTail = node.get();
		(this->tail)->next = std::move(node);
		this->tail = newTail;
		newTail = nullptr;
	}

	(this->conVar).notify_one();
}

template<typename T>
void Queue<T>::push(T&& value)
{
	std::shared_ptr<T> nodeData{ std::make_shared<T>(std::move(value)) };
	std::unique_ptr<Node<T>> node{ new Node<T>{} };
	{
		std::lock_guard<std::mutex> lockGuard{ this->tailM };
		(this->tail)->data = nodeData;
		Node<T>* newTail = node.get();
		(this->tail)->next = std::move(node);
		this->tail = newTail;
		newTail = nullptr;
	}

	(this->conVar).notify_one();
}

template<typename T>
std::shared_ptr<T> Queue<T>::wait_pop()
{
	std::unique_ptr<std::mutex> uniqueLck(this->headM);
	(this->conVar).wait(this->headM, [] {return ((this->head.get() == this->getTal()) ? false, true); });
	std::shared_ptr<T> value{ std::move((this->head)->data) };
	this->head = std::move((this->head)->next);

	return value;
}

int main()
{
	Queue<int> que{ 1, 2, 3, 4 };

	std::cout << que.empty() << std::endl;
	que.push(20);

	return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/785371

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值