#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保护多数据会引发另外现象死锁