首页 > 编程语言 >c++ queue在多线程中的使用

c++ queue在多线程中的使用

时间:2024-02-28 23:23:26浏览次数:32  
标签:std include int c++ queue mutex 多线程 empty

queue队列,先进先出。

多线程的一种使用案例:

生产者每3s push一个元素

消费者每5s才能 pop一个元素(队首)

那么,2个消费者就可以及时地消耗掉push的元素。

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

std::queue<int> m_queue;
std::mutex m_mutex;
std::condition_variable _not_empty;

void funcIn()
{
    int i = 0;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(3));
        std::cout << "\t" << i << std::endl;
        std::unique_lock<std::mutex> lck(m_mutex);
        m_queue.push(i);
        _not_empty.notify_one();

        i++;
    }
}

void funcOut()
{
    int i = -1;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));

        std::unique_lock<std::mutex> lck(m_mutex);
        _not_empty.wait(lck, [](){
            return !m_queue.empty();
            });
        i=m_queue.front();
        m_queue.pop();
        std::cout << i << std::endl;
    }
}

int main()
{
    std::thread producer(funcIn);
    std::thread consumer1(funcOut);
    std::thread consumer2(funcOut);

    producer.join();
    consumer1.join();
    consumer2.join();

    return 0;
}

如果需要push多个,可以使用struct

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

struct Data
{
    int i = 0;
    int j = 0;
};

std::queue<Data> m_queue;
std::mutex m_mutex;
std::condition_variable _not_empty;

void funcIn()
{
    int i = 0;
    Data data;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(3));
        std::cout << "\t" << i << std::endl;
        std::unique_lock<std::mutex> lck(m_mutex);
        data.i = i;
        m_queue.push(data);
        _not_empty.notify_one();

        i++;
    }
}

void funcOut()
{
    int i = -1;
    Data data;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));

        std::unique_lock<std::mutex> lck(m_mutex);
        _not_empty.wait(lck, [](){
            return !m_queue.empty();
            });
        data= m_queue.front();
        m_queue.pop();
        std::cout << data.i<<" "<<data.j << std::endl;
    }
}

int main()
{
    std::thread producer(funcIn);
    std::thread consumer1(funcOut);
    std::thread consumer2(funcOut);

    producer.join();
    consumer1.join();
    consumer2.join();

    return 0;
}

当然,可以直接使用大牛实现的多线程的队列 concurrentqueue、blockingconcurrentqueue

GitHub - cameron314/concurrentqueue: A fast multi-producer, multi-consumer lock-free concurrent queue for C++11

只需要将下图3个头文件放入工程目录即可

不再需要自己加锁、条件等待,可读性较高。

#include <iostream>
#include<thread>
#include"blockingconcurrentqueue.h"

moodycamel::BlockingConcurrentQueue<int> m_queue;

void funcIn()
{
    int i = 0;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(3));
        m_queue.try_enqueue(i);    
        std::cout << "\t" << i << std::endl;

        i++;
    }
}

void funcOut()
{
    int i = -1;
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));        
        m_queue.wait_dequeue(i);
        std::cout << i << std::endl;
    }
}

 

标签:std,include,int,c++,queue,mutex,多线程,empty
From: https://www.cnblogs.com/xixixing/p/18042299

相关文章

  • [没啥用科技] C++ 分数类
    虽然说用的是结构体,但已经实现了同类型加减乘除和分数与整型的加减乘除。写的有点难看,并伴有大常数,以后来改。#include<bits/stdc++.h>#include<bits/extc++.h>#definelllonglong#defineldblongdouble#definem_p(a,b)make_pair(a,b)usingnamespacestd;using......
  • c++ primer ch2笔记
    ch22.1基本内置类型C++基本内置类型void算术类型整形(包括字符,bool)浮点型最小尺寸:整形尺寸大小受编译器影响,但是至少会保证一个最小尺寸,int最小尺寸2字节相互关系:int至少和一个short一样大无符号类型:unsignedint、unsignedlong类型转换规则:布......
  • rust与python/c++语法区别
    if/matchpubfnanimal_habitat(animal:&str)->&'staticstr{letid=ifanimal=="crab"{//id等于(或拥有)了一个匿名函数的返回值1}elseifanimal=="gopher"{2}elseifanimal=="snake"......
  • C++的异常处理究竟有多慢?
    我们能在各处看到“C++的异常很慢,不要用”这样的言论,不过很少有人告诉你,C++的异常到底有多慢,以及它为什么这么慢。本文会详细介绍C++在抛出以及捕获异常时,代码到底做了什么,以及我们使用C++异常到底付出了多少代价。抛出异常要了解异常处理到底做了什么,我们需要深入到汇编语言来......
  • 通过前向声明解决C++中两个头文件互相引用的问题
    在C++中,当两个头文件互相引用时,可以通过前向声明来避免直接的#include依赖,从而解决循环依赖的问题。前向声明是在一个头文件中声明另一个头文件中的类或类型的名称,而不包括其具体的实现细节。这样,每个头文件只依赖对方的声明,而不需要依赖对方的定义,从而打破了循环依赖。以下是如......
  • OpenCV计数应用 c++(QT)
    一、前言为了挑战一下OpenCV的学习成果,最经一直在找各类项目进行实践。机缘巧合之下,得到了以下的需求:要求从以下图片中找出所有的近似矩形的点并计数,重叠点需要拆分单独计数。二、解题思路1.图片作二值化处理autoimage=cv::imread("points.jpg");cv::Matborder;//为......
  • C++临时对象
    C++临时对象临时对象的构造与析构在C++中,临时对象(TemporaryObject)是在表达式求值过程中创建的、无名字的对象。它们通常用于存储中间结果或作为函数调用的参数或返回值,其生命周期通常仅限于表达式的求值过程中。临时对象的构建和析构与普通对象类似,只是它们的生命周期通常比......
  • C++ 点的线性拟合 y(x)=ax+b
    一、简单分析点的线性拟合是一般实验数据处理最常用的方法。下面考虑一个用n个数据点拟合成直线的问题,直线模型为y(x)=ax+b这个问题称为线性回归。设变量y随自变量x变化,给定n组观测数据(xi,yi),用直线来拟合这些点,其中a,b是直线的斜率和截距,称为回归系数。为确定......
  • c# winform 多线程
    ​  privateTaskSchedulermpr_ts_UIContext;    privatevoidbutton1_Click(objectsender,EventArgse)    {      progressBar1.Visible=true;      progressBar1.Value=0; //清空进度条      progress......
  • 微软 官方 .net 组件 下载 directx组件 下载 viual c++ 组件 下载 官方 修复DLL方
    下载.NETFramework|免费官方下载(microsoft.com).NETFramework是仅适用于Windows版本的.NET,用于生成客户端和服务器应用程序。升级应用在VisualStudio中单击几下即可将应用从.NETFramework升级到最新的.NET。  DownloadDirectXEnd-UserRuntimefromO......