成都网站制,杭州市河道建设中心网站,德州市住房建设局网站,孝感市门户std::stack容器的接口包括 empty(), size(), top(), push(), pop()等。
问题
其原接口在多线程的情况下#xff0c;会持续很多问题。
例如#xff0c;在std::stack容器的接口中#xff0c;在多线程下应用时#xff0c;empty()和size()的结果是不可信的。因为尽管在某线程…std::stack容器的接口包括 empty(), size(), top(), push(), pop()等。
问题
其原接口在多线程的情况下会持续很多问题。
例如在std::stack容器的接口中在多线程下应用时empty()和size()的结果是不可信的。因为尽管在某线程调用empty()或size()时返回值可能是正确的但是一旦函数返回其他线程就不再受限从而能自由地访问栈容器可能马上会有新元素入栈或者现有的元素立即出栈这会使前面线程得到的结果失效。
其次top()和pop()之间也存在着竞争条件例如
线程A线程Bif(!s.empty());if(!s.empty()); int const value s.top(); int const value s.top();s.pop()do_something(value);s.pop()do_something(value);
假设当前只有两个线程正在运行且在两个top()调用之间不存在其他操作那么栈容器不会被更改即两个线程会得到相同的值。另外在top()与pop()的调用之间也没有其他调用结果栈顶元素被调用了两次但栈顶的第二个元素却始终没被读取就丢弃了。
解决方法
为了线程安全在每次操作之前都加锁
面对第二个问题将top()和pop()操作合二为一
#include memory
#include mutex
#include stackusing namespace std;struct empty_stack :std::exception
{const char* what() const throw();
};templatetypename T
class threadsafe_stack
{
private:stackT data;mutable mutex m;public:threadsafe_stack() {};threadsafe_stack(const threadsafe_stack other){lock_guardmutex lock(other.m);data other.data;}threadsafe_stack operator(const threadsafe_stack) delete;void push(T new_value){lock_guardmutex lock(m);data.push(move(new_value));}shared_ptrT pop(){lock_guardmutex lock(m);if (data.empty()) throw empty_stack();shared_ptrTconst res(std::make_sharedT(data.top()));data.pop();return res;}void pop(T value){lock_guardmutex lock(m);if (data.empty()) throw empty_stack();value data.top();data.pop();}bool empty() const{lock_guardmutex lock(m);return data.empty();}
};