线程安全栈的实现代码:
stack.hpp
struct empty_stack: std::exception {
const char*nwhat() const throw();
};
template<typename T>
class threadsafe_stack {
private:
std::stack<T> data;
mutable std::mutex m;
public:
threadsafe_stack() {}
threadsafe_stack(const threadsafe_stack &other)
{
std::lock_guard<std::mutex> lock(other.m);
data = other.data;
}
threadsafe_stack &operator = (const threadsafe_stack &) =delete;
void push(T new_value)
{
std::lock_guard<std::mutex> lock(m);
data.push(std::move(new_value));
}
std::shared_ptr<T> pop()
{
std::lock_guard<std::mutex> lock(m);
if(data.empty())
throw empty_stack();
std::shared_ptr<T> const res(std::make_shared<T>(std::move(data.top())));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty())
throw empty_stack();
value = std::move(data.top());
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
};
测试代码
int main(void)
{
threadsafe_stack<int> si;
si.push(5);
//si.pop();
if(!si.empty())
{
//std::cout << "pop is operator" << std::endl;
//int x;
//si.pop(x);
//std::cout << "x: " << x << std::endl;
auto a = si.pop();
std::cout << "a : " << *a << std::endl;
}
return 0;
}
原理解析
基本的线程安全是通过使用互斥锁m保护成员函数来实现的。就确保了同一时间只有一个线程在存取数据,并且使用std::lock_guard<>保证在成员函数结束的时候互斥元不会被锁定。因为所有的成员函数都使用std::lock_guard<>来保护数据,所以多个线程调用stack的成员函数是安全的。
项目源码:
https://github.com/ykevin/blog/tree/master/concurrency/stack