当前位置: 首页 > article >正文

C++ 并发专题 - 实现一个线程安全的队列

一:概述

        本文利用 C++ 标准库中的多线程、条件变量、互斥锁等工具来实现一个线程安全的队列,并且使用多个线程来向队列中添加和获取数据。 

二:实现过程:

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

template <typename T>
class ThreadSafeQueue {
public:
    // 向队列中添加元素
    void push(const T& value) {
        std::lock_guard<std::mutex> lock(mutex_);
        queue_.push(value);
        cond_var_.notify_one();  // 通知一个等待的线程
    }

    // 从队列中取出元素,如果队列为空,阻塞等待
    T pop() {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_var_.wait(lock, [this] { return !queue_.empty(); });  // 等待直到队列非空
        T value = queue_.front();
        queue_.pop();
        return value;
    }

    // 判断队列是否为空
    bool empty() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return queue_.empty();
    }

private:
    mutable std::mutex mutex_;            // 互斥锁,保护队列
    std::queue<T> queue_;                 // 基础队列
    std::condition_variable cond_var_;   // 条件变量,用于队列为空时的等待
};

// 示例:使用线程安全队列
void producer(ThreadSafeQueue<int>& queue, int numItems) {
    for (int i = 0; i < numItems; ++i) {
        queue.push(i);
        std::cout << "Produced: " << i << std::endl;
    }
}

void consumer(ThreadSafeQueue<int>& queue, int numItems) {
    for (int i = 0; i < numItems; ++i) {
        int item = queue.pop();
        std::cout << "Consumed: " << item << std::endl;
    }
}

int main() {
    ThreadSafeQueue<int> queue;

    const int numItems = 10;
    const int numProducers = 2;
    const int numConsumers = 2;

    std::vector<std::thread> threads;

    // 启动生产者线程
    for (int i = 0; i < numProducers; ++i) {
        threads.push_back(std::thread(producer, std::ref(queue), numItems / numProducers));
    }

    // 启动消费者线程
    for (int i = 0; i < numConsumers; ++i) {
        threads.push_back(std::thread(consumer, std::ref(queue), numItems / numConsumers));
    }

    // 等待所有线程完成
    for (auto& thr : threads) {
        thr.join();
    }

    return 0;
}


http://www.kler.cn/a/456370.html

相关文章:

  • 微信流量主挑战:用户破16!新增文档转换(新纪元3)
  • Xilinx PCIe高速接口入门实战(三)
  • 在K8S中,如果Pod处于不健康状态如何排查?
  • 阶乘分布(Factorial Distribution)和变分推断中的均场(Mean Field)方法:中英双语
  • 缓存管理自动化:JuiceFS 企业版 Cache Group Operator 新特性发布
  • 学习笔记(C#基础书籍)-- C#高级应用
  • 4.基于 Couchbase 构建数据仓库的元数据管理方案
  • 【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】
  • 钉钉机器人发送excel表(简易版)
  • 使用ArcGIS/ArcGIS pro绘制六边形/三角形/菱形渔网图
  • vim文本编辑器常用命令和快捷键
  • Modern C++ std::atomic简介
  • neo4j无法导入csv文件
  • 渗透测试入门DVWA 教程1:环境搭建
  • 【WRF模拟】最高/最低日气温偏高/偏低的参数调整
  • 【Android】application@label 属性属性冲突报错
  • 潇洒郎:部署Dify, 安装Ollama,Ollama下载模型,Dify配置模型
  • JavaScript甘特图 dhtmlx-gantt
  • 面试场景题系列:设计URL短链
  • 深度学习中的参数初始化
  • Anaconda 安装与虚拟环境创建完整指南
  • jetbrains HTTPS 请求与响应流量分析报告【二】
  • C语言实践中的补充知识 Ⅶ
  • 在国产电脑上运行PDFSAM软件使用pdf分割合并交替混合处理pdf文档
  • 基于 Vant UI + Redisson BitSet 实现签到日历
  • springBoot发布https服务及调用