实现阻塞队列

103 阅读1分钟

在 C++ 中实现阻塞队列通常需要结合互斥锁(mutex)和条件变量(condition variable)来实现。下面是一个简单的阻塞队列的示例实现:

#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

template<typename T>
class BlockingQueue {
private:
    std::queue<T> queue_;
    std::mutex mutex_;
    std::condition_variable cv_;

public:
    void push(const T& value) {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            queue_.push(value);
        }
        cv_.notify_one();
    }

    T pop() {
        std::unique_lock<std::mutex> lock(mutex_);
        cv_.wait(lock, [this] { return !queue_.empty(); });
        T value = queue_.front();
        queue_.pop();
        return value;
    }
};

// 示例用法
BlockingQueue<int> bq;

void producer() {
    for (int i = 0; i < 5; ++i) {
        bq.push(i);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void consumer() {
    for (int i = 0; i < 5; ++i) {
        int value = bq.pop();
        std::cout << "Consumer received: " << value << std::endl;
    }
}

int main() {
    std::thread producer_thread(producer);
    std::thread consumer_thread(consumer);

    producer_thread.join();
    consumer_thread.join();

    return 0;
}

在这个示例中,BlockingQueue 类封装了一个标准库队列(std::queue),并使用互斥锁(std::mutex)和条件变量(std::condition_variable)来实现阻塞队列的功能。

  • push() 函数用于向队列中添加元素,在添加元素之前使用互斥锁保护队列的操作,并在添加完成后通知等待的线程。
  • pop() 函数用于从队列中取出元素,在取出元素之前使用条件变量等待队列不为空,并在取出元素后返回该元素的值。

在生产者线程中,循环向阻塞队列中添加数据;在消费者线程中,循环从阻塞队列中取出数据。由于阻塞队列的特性,如果队列为空,消费者线程会阻塞等待,直到队列中有数据可用。