c++并发编程(六)—— 基于锁的并发数据结构设计

在我们进行并发编程的时候,如果多线程使用到了数据结构,那么程序设计过程中需要保证此数据结构的正确同步。有两种方法:

1、选择单独的互斥元与外部锁来保护数据

2、设计一个可以同时访问的数据结构

其中前几节我们涉及到了第一种方法,现在我们重点描述下第二种方法。

使用锁和条件变量的线程安全队列

template
class threadsafe_queue
{
private:
	mutable std::mutex mut;
	std::queue data_queue;
	std::condition_variable data_cond;
public:
	threadsafe_queue()
	{}

	void push(T new_value)
	{
		std::lock_guard lk(mut);
		data_queue.push(std::move(new_value));
		data_cond.notify_one();
	}

	void wait_and_pop(T& value)
	{
		std::unique_lock lk(mut);
		data_cond.wait(lk, [this] {return !data_queue.empty(); });
		value = std::move(data_queue.front());
		data_queue.pop();
	}

	std::shared_ptr wait_and_pop()
	{
		std::unique_lock lk(mut);
		data_cond.wait(lk, [this] {return !data_queue.empty(); });
		std::shared_ptr res(
			std::make_shared(std::move(data_queue.front())));
		data_queue.pop();
		return res;
	}

	bool try_pop(T& value)
	{
		std::lock_guard lk(mut);
		if (data_queue.empty())
			return false;
		value = std::move(data_queue.front());
		data_queue.pop();
	}

	std::shared_ptr try_pop()
	{
		std::lock_guard lk(mut);
		if (data_queue.empty())
			return std::shared_ptr();
		std::shared_ptr res(
			std::make_shared(std::move(data_queue.front())));
		data_queue.pop();
		return res;
	}

	bool empty() const
	{
		std::lock_guard lk(mut);
		return data_queue.empty();
	}
};

 

你可能感兴趣的:(c++,多线程)