c++ concurrency in action 3.5cpp

#include <exception>
#include <stack>
#include <mutex>
#include <memory>
#include <iostream>

//Cargill 困境就是说在stack 中大内存的复制,如果pop出来没位置,造成数据的缺失
struct empty_stack1 : std::exception
{
	const char* what() const throw()
	{
		return "shut the fuck up empty stack";
	}

};


template<typename T>
class threadsafe_stack
{
private:
	std::stack<T> data;
	mutable std::mutex m;
public:
	threadsafe_stack() {}
	threadsafe_stack(const threadsafe_stack& other)//为了防止mutex也被copy
	{
		std::lock_guard<std::mutex> lock(other.m);
		data = other.data;
	}
	//threadsafe_stack& operator=(threadsafe_stack&) = delete;

	void push(T new_value)
	{
		std::lock_guard<std::mutex> lock(m);
		data.push(new_value);
	}
	std::shared_ptr<T> pop()
	{
		std::lock_guard<std::mutex> lock(m);
		if (data.empty()) throw empty_stack1();
		std::shared_ptr<T> const res(std::make_shared<T>(data.top()));//用shared指针来防止pop和top竞争
		data.pop();
		return res;
	}
	int top()
	{
		return data.top();
	}
	void pop(T& value)
	{
		std::lock_guard<std::mutex> lock(m);
		if (data.empty()) throw empty_stack1();
		value = data.top();
		data.pop();
	}
	bool empty() const
	{
		std::lock_guard<std::mutex> lock(m);
		return data.empty();
	}
};

int main()
{
	threadsafe_stack<int> si;
//	si.push(5);
	threadsafe_stack<int> sb =si;
	std::cout << sb.pop();
	
	si.pop();
	if (!si.empty())
	{
		int x;
		si.pop(x);
	}
	std::cin.get();

}
//一个全局mutex保护所有data容易造成低效,早期的linux系统就是这样,造成了多核的低效,但是如果多mutex保护多数据会引发另外现象死锁

猜你喜欢

转载自blog.csdn.net/fly1ng_duck/article/details/81099887