之前有一节中,我们使用mutex实现了一个线程间安全的堆栈。这一节,我们使用条件变量来实现一个线程间安全的队列。
标准库中的std::queue<>的接口定义如下:
template <class T, class Container = std::deque<T> >
class queue {
public:
explicit queue(const Container&);
explicit queue(Container&& = Container());
queue(queue&& q);
template <class Alloc> explicit queue(const Alloc&);
template <class Alloc> queue(const Container&, const Alloc&);
template <class Alloc> queue(Container&&, const Alloc&);
template <class Alloc> queue(queue&&, const Alloc&);
queue& operator=(queue&& q);
void swap(queue&& q);
bool empty() const;
size_type size() const;
T& front();
const T& front() const;
T& back();
const T& back() const;
void push(const T& x);
void push(T&& x);
void pop();
};
忽略构造,赋值和交换运算,还剩下以下三类操作:
- 查询队列状态:empty()和size()
- 查询队列中的元素:front()和back()
- 修改队列中的元素:push()、pop()和emplace()
和stack类似,这些接口对存在竞争条件。我们需要合并front()和pop()操作。这里我们需要实现pop操作的两个变种:
- try_pop():尝试从队列中pop数据并立即返回。
- wait_and_pop():等待挂起直到队列中有数据被获取。
#include <memory> // 为了使用std::shared_ptr
template<typename T>
class threadsafe_queue
{
p