《C++ Concurrency in Action》笔记7 mutex(3)pop和top问题之示例

来源:互联网 发布:三维模具设计软件 编辑:程序博客网 时间:2024/05/17 23:28

采用上一篇所说的方案一和方案三定义的一个线程安全的stack,它其实是个stack的包装类,代码如下:

struct empty_stack : exception{const char* what() const throw(){return "the stack is empty";};};template<typename T>class threadsafe_stack{private:stack<T> data;mutable mutex m;public:threadsafe_stack() {}threadsafe_stack(const threadsafe_stack& other){lock_guard<mutex> lock(other.m);data = other.data;}threadsafe_stack& operator=(const threadsafe_stack&) = delete;void push(T new_value){lock_guard<mutex> lock(m);data.push(new_value);}shared_ptr<T> pop(){lock_guard<mutex> lock(m);if (data.empty()) throw empty_stack();shared_ptr<T> const res(make_shared<T>(data.top()));data.pop();return res;}void pop(T& value){lock_guard<mutex> lock(m);if (data.empty()) throw empty_stack();value = data.top();data.pop();}bool empty() const{lock_guard<mutex> lock(m);return data.empty();}};
为了最大化其安全性,整个stack的操作都被严格限制。赋值操作被删除,但是可以拷贝构造,假设其元素类型支持拷贝。2个pop()函数有可能抛出empty_stack异常,保证即使stack为空的情况下执行pop也没有问题。接口由原来的5个变为现在的3个:push()、pop()、empty(),尽管empty()有些多余。

注意他的拷贝构造函数,他没有在初始化列表中初始化成员,而是在函数体内赋值。这样做的目的是为了让mutex起到保护作用。


阅读全文
0 0