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

 

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