BlockDeque.h
cpp
#ifndef BLOCKQUEUE_H
#define BLOCKQUEUE_H
#include <mutex>
#include <deque>
#include <condition_variable>
#include <cassert>
#include <chrono>
template<class T>
class BlockDeque {
public:
explicit BlockDeque(size_t MaxCapacity = 1000);
~BlockDeque();
void clear();
bool empty();
bool full();
void Close();
size_t size();
size_t capacity();
T front();
T back();
void push_back(const T &item);
void push_front(const T &item);
bool pop(T &item);
bool pop(T &item, int timeout);
void flush();
private:
std::deque<T> deq_; // 底层队列
size_t capacity_; // 队列容量
std::mutex mtx_; // 互斥锁
bool isClose_; // 队列是否关闭
std::condition_variable condConsumer_; // 消费者条件变量
std::condition_variable condProducer_; // 生产者条件变量
};
#endif // BLOCKQUEUE_H
BlockDeque.cpp
cpp
#include "BlockDeque.h"
#include <iostream>
#include <thread>
#include <chrono>
// 构造函数
template<class T>
BlockDeque<T>::BlockDeque(size_t MaxCapacity) : capacity_(MaxCapacity) {
assert(MaxCapacity > 0);
isClose_ = false;
}
// 析构函数
template<class T>
BlockDeque<T>::~BlockDeque() {
Close();
}
// 关闭队列
template<class T>
void BlockDeque<T>::Close() {
{
std::lock_guard<std::mutex> locker(mtx_);
deq_.clear();
isClose_ = true;
}
condProducer_.notify_all();
condConsumer_.notify_all();
}
// 清空队列
template<class T>
void BlockDeque<T>::clear() {
std::lock_guard<std::mutex> locker(mtx_);
deq_.clear();
}
// 队列是否为空
template<class T>
bool BlockDeque<T>::empty() {
std::lock_guard<std::mutex> locker(mtx_);
return deq_.empty();
}
// 队列是否已满
template<class T>
bool BlockDeque<T>::full() {
std::lock_guard<std::mutex> locker(mtx_);
return deq_.size() >= capacity_;
}
// 获取队列大小
template<class T>
size_t BlockDeque<T>::size() {
std::lock_guard<std::mutex> locker(mtx_);
return deq_.size();
}
// 获取队列容量
template<class T>
size_t BlockDeque<T>::capacity() {
std::lock_guard<std::mutex> locker(mtx_);
return capacity_;
}
// 获取队首元素
template<class T>
T BlockDeque<T>::front() {
std::lock_guard<std::mutex> locker(mtx_);
return deq_.front();
}
// 获取队尾元素
template<class T>
T BlockDeque<T>::back() {
std::lock_guard<std::mutex> locker(mtx_);
return deq_.back();
}
// 向队尾添加元素
template<class T>
void BlockDeque<T>::push_back(const T &item) {
std::unique_lock<std::mutex> locker(mtx_);
while (deq_.size() >= capacity_) {
condProducer_.wait(locker);
}
deq_.push_back(item);
condConsumer_.notify_one();
}
// 向队首添加元素
template<class T>
void BlockDeque<T>::push_front(const T &item) {
std::unique_lock<std::mutex> locker(mtx_);
while (deq_.size() >= capacity_) {
condProducer_.wait(locker);
}
deq_.push_front(item);
condConsumer_.notify_one();
}
// 从队首弹出元素
template<class T>
bool BlockDeque<T>::pop(T &item) {
std::unique_lock<std::mutex> locker(mtx_);
while (deq_.empty()) {
condConsumer_.wait(locker);
if (isClose_) {
return false;
}
}
item = deq_.front();
deq_.pop_front();
condProducer_.notify_one();
return true;
}
// 从队首弹出元素,带超时功能
template<class T>
bool BlockDeque<T>::pop(T &item, int timeout) {
std::unique_lock<std::mutex> locker(mtx_);
while (deq_.empty()) {
if (condConsumer_.wait_for(locker, std::chrono::seconds(timeout)) == std::cv_status::timeout) {
return false;
}
if (isClose_) {
return false;
}
}
item = deq_.front();
deq_.pop_front();
condProducer_.notify_one();
return true;
}
// 刷新队列(唤醒消费者)
template<class T>
void BlockDeque<T>::flush() {
condConsumer_.notify_one();
}
// 测试主函数
int main() {
BlockDeque<int> queue(5); // 最大容量为 5
// 生产者线程
auto producer = [&queue]() {
for (int i = 0; i < 10; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产延迟
queue.push_back(i);
std::cout << "Produced: " << i << std::endl;
}
};
// 消费者线程
auto consumer = [&queue]() {
for (int i = 0; i < 10; ++i) {
int item;
if (queue.pop(item)) {
std::cout << "Consumed: " << item << std::endl;
}
}
};
// 测试超时消费者线程
auto timeout_consumer = [&queue]() {
int item;
if (queue.pop(item, 2)) { // 等待 2 秒
std::cout << "Timeout Consumer Got: " << item << std::endl;
} else {
std::cout << "Timeout Consumer Failed: Timed out" << std::endl;
}
};
// 启动线程
std::thread producerThread(producer);
std::thread consumerThread(consumer);
producerThread.join();
consumerThread.join();
// 测试超时功能
std::cout << "Testing Timeout Consumer..." << std::endl;
timeout_consumer();
return 0;
}
文件结构
cpp
.
├── BlockDeque.h // 声明头文件
├── BlockDeque.cpp // 实现源文件 + 测试主函数