线程安全栈这个队列唯一需要注意的是条件变量的使用,分别在pop和push,三个地方使用了,当栈为空就会堵塞所有的线程在pop,push了一个就会解锁一个线程,进行pop。
如果不记得条件变量的作用,那么回忆一下
wait()用来等一个东西
如果第二个参数,lambda返回值是true,那wait()直接返回;
如果第二个参数lambda表达式返回值是false,那么wait()将解锁互斥量,并堵塞到本行
那么堵塞到什么时候呢?堵塞到其他线程调用notify_one()成员函数为止
如果wait()没有第二个参数:那么跟第二个参数lambda表达式返回值为false效果一样
wait()将解锁互斥量,并堵塞到本行,堵塞到其他某个线程调用notify_one()成员函数为止
struct empty_stack :std::exception
{
const char* what()noexcept { return ""; }
};
template
class threadsfe_stack {
private:
std::stackdata;
mutable std::mutex m;
public:
threadsfe_stack(){}
threadsfe_stack(const threadsfe_stack& other)
{
std::lock_guardlock(other.m);
data = other.data;
}
threadsfe_stack& operator=(const threadsfe_stack&) = delete;
void push(T new_value)
{
std::lock_guardlock(m);
data.push(std::move(new_value));
}
std::shared_ptrpop()
{
std::lock_guardlock(m);
if (data.empty())throw empty_stack();
std::shared_ptrconst res(std::make_shared(data.top()));
data.pop();
return res;
}
void pop(T& value)
{
std::lock_guardlock(m);
if (data.empty())throw empty_stack();
value = data.top();
data.pop();
}
bool empty()const
{
std::lock_guardlock(m);
return data.empty();
}
};
线程安全队列
暑期编程PK赛
得CSDN机械键盘等精美礼品!


