C++的线程安全的队列

 

(1)这个实现要求构建工具支持C++11的atomic mutex condition_veriable功能。这是C++11的基础特性,一般2011年以后的C++编译器都能支持。 例如,visual studio 2012以上。

(2)这个类的实现中有两处使用了unique_lock而不是lock_guard,这是data_cond.wait所需要的,unique_lock是lock_guard的增强版。

通过std::move的使用(前提是我们实现的类型T定义了移动构造函数和移动赋值函数),能利用移动语义带来的性能优势。

使用shared_ptr返回元素,用户无需释放元素的内存。

 

#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

template
class threadsafe_queue
{
public:
	threadsafe_queue()
	{
		m_bTermination = false;
	}
	~threadsafe_queue(void)
	{

	}
	//(1)没有调用termination时,每调用一次出队一个元素,直到队列为空本方法阻塞线程。
	//(2)在调用了termination后,本方法永不阻塞,如果原本已经处于阻塞状态,接触阻塞状态。
	//(3)返回true时,value值有效。返回false时,value值无效。调用了termination且队列为空时返回false.
	bool wait_and_pop(T& value)
	{
		unique_lock lk(mut);
		data_cond.wait(lk,[this]{return ((!data_queue.empty())||m_bTermination);});
		//不为空则出队
		if (!data_queue.empty())
		{
			value = move(*data_queue.front());
			data_queue.pop();
			return true;
		}
		//队列为空则返回失败
		return false;
	}

	//队列为空返回false
	bool try_pop(T& value)
	{
		lock_guard lk(mut);
		if (data_queue.empty())
		{
			return false;
		}
		value = move(*data_queue.front());
		data_queue.pop();
		return true;
	}
	std::shared_ptr wait_and_pop()
	{
		unique_lock lk(mut);
		data_cond.wait(lk,[this]{return ((!data_queue.empty())||m_bTermination);});
		if (!data_queue.empty())
		{
			shared_ptr res = data_queue.front();
			data_queue.pop();
			return res;
		}
		return nullptr;
	}
	//队列为空返回null
	std::shared_ptr try_pop()
	{
		lock_guard lk(mut);
		if(data_queue.empty())
		{
			return nullptr;
		}
		shared_ptr res = data_queue.front();
		data_queue.pop();
		return res;
	}
	//插入一项
	void push(T new_value)
	{
		if (m_bTermination)
		{
			return;
		}
		shared_ptr data(make_shared(move(new_value)));
		lock_guard lk(mut);
		data_queue.push(data);
		data_cond.notify_one();
	}
	bool empty()
	{
		lock_guard lk(mut);
		return data_queue.empty();
	}
	int size()
	{
		lock_guard lk(mut);
		return data_queue.size();
	}
	//设置队列为退出状态。在退出状态下,忽略入队,可以执行出队,但当队列为空时,wait_and_pop不会阻塞。
	void termination()
	{
                lock_guard lk(mut);
		m_bTermination = true;
		data_cond.notify_all();
	}
	//是退出状态吗
	bool is_termination()
	{
		return m_bTermination;
	}
private:
	mutex mut;
	queue> data_queue;
	condition_variable data_cond;
	atomic m_bTermination;
};

 

你可能感兴趣的:(C++11)