C++线程安全队列

在 C++ 中,多线程队列(queue)的实现通常需要考虑线程安全问题,特别是在多个线程需要同时对队列进行操作时。C++ 标准库中的 std::queue 并不是线程安全的,因此我们需要引入额外的机制来确保线程安全。常用的方法是使用互斥锁(mutex)和条件变量(condition variable)。

下面是一个使用 std::queue 实现线程安全队列的示例:

cpp 复制代码
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>

template <typename T>
class ThreadSafeQueue {
private:
    std::queue<T> queue;
    std::mutex mtx;
    std::condition_variable cv;

public:
    void push(T value) {
        std::lock_guard<std::mutex> lock(mtx);
        queue.push(value);
        cv.notify_one(); // 通知一个等待线程
    }

    T pop() {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [this]() { return !queue.empty(); }); // 等待队列非空
        T value = queue.front();
        queue.pop();
        return value;
    }

    bool empty() {
        std::lock_guard<std::mutex> lock(mtx);
        return queue.empty();
    }
};

void producer(ThreadSafeQueue<int>& tsq) {
    for (int i = 0; i < 10; ++i) {
        std::cout << "Producing: " << i << std::endl;
        tsq.push(i);
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void consumer(ThreadSafeQueue<int>& tsq) {
    for (int i = 0; i < 10; ++i) {
        int value = tsq.pop();
        std::cout << "Consuming: " << value << std::endl;
    }
}

int main() {
    ThreadSafeQueue<int> tsq;

    std::thread prod_thread(producer, std::ref(tsq));
    std::thread cons_thread(consumer, std::ref(tsq));

    prod_thread.join();
    cons_thread.join();

    return 0;
}

在这个示例中,我们定义了一个模板类 ThreadSafeQueue,它使用 std::queue 作为基础容器,并通过 std::mutexstd::condition_variable 实现了线程安全的 pushpop 操作。

  • push 方法向队列中添加元素,并通知一个等待的线程。
  • pop 方法从队列中取出元素,如果队列为空,则等待直到有元素被添加进来。
  • empty 方法检查队列是否为空。

main 函数中,我们创建了两个线程:一个生产者线程(producer),它负责向队列中添加元素;一个消费者线程(consumer),它负责从队列中取出元素。通过互斥锁和条件变量,我们确保了这些操作的线程安全性。

相关推荐
小坏坏的大世界34 分钟前
C++ STL常用容器总结(vector, deque, list, map, set)
c++·算法
liulilittle2 小时前
C++ TAP(基于任务的异步编程模式)
服务器·开发语言·网络·c++·分布式·任务·tap
励志要当大牛的小白菜3 小时前
ART配对软件使用
开发语言·c++·qt·算法
PAK向日葵4 小时前
【算法导论】如何攻克一道Hard难度的LeetCode题?以「寻找两个正序数组的中位数」为例
c++·算法·面试
QQ_4376643148 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
liulilittle10 小时前
C++/CLI与标准C++的语法差异(一)
开发语言·c++·.net·cli·clr·托管·原生
小狄同学呀10 小时前
VS插件报错,g++却完美编译?API调用错因分析
c++
程序员编程指南10 小时前
Qt 数据库连接池实现与管理
c语言·数据库·c++·qt·oracle
小乖兽技术10 小时前
C#与C++交互开发系列(二十四):WinForms 应用中嵌入C++ 原生窗体
c++·c#·交互
张北北.10 小时前
【深入底层】C++开发简历4+4技能描述6
java·开发语言·c++