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

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;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章