在某些情况下使用队列处理消耗元素

时间:2018-08-13 12:30:38

标签: c++ multithreading asynchronous queue c++14

我有一个线程推送到队列,另一个线程消耗队列中的元素。 其中一个元素的处理是异步的,但是在此过程中,我不想处理其他元素。 (假设输出流和队列是线程安全的)

我想知道实现消耗线程的最佳方法是什么...我认为while(true)和条件不是最佳选择。

实现简单吗(process2必须是异步的)。

#include <iostream>
#include <queue>
#include <thread>
#include <atomic>
#include <future>

std::atomic_bool isProcess2Processing{false};

void process0()
{
    std::cout << "process0" << std::endl;
}

void process1()
{
    std::cout << "process1" << std::endl;
}

void process2()
{
    std::async(std::launch::async, []() { isProcess2Processing = true; std::cout << "start process2" << std::endl; while (std::rand() > 10000) {}; std::cout << "finished proces2" << std::endl; isProcess2Processing = false; });
}

void consume(int x)
{
    if (x == 0)
    {
        process0();
    }
    else if (x == 1)
    {
        process1();
    }
    else
    {
        process2();
    }
}

int main()
{
    std::queue<int> q;

    std::thread consumingThread([&q]() {
        while (true) {
            if (!q.empty() && !isProcess2Processing) {
                consume(q.front());
                q.pop();
            }
        }
    });

    while (true)
    {
        q.push(std::rand() % 3);
    }
}

1 个答案:

答案 0 :(得分:0)

  

我想知道实现消耗线程的最佳方法是什么...我认为   while(true)和条件不是最佳选择。

您在这里的考虑是有道理的:使用这样的while循环(即不涉及任何 waiting )的最大问题是浪费CPU时间和精力。您的辅助线程(以及每个给定主线程的代码)在没有明显原因的情况下将CPU内核全部保留一段时间,这样其他任务就无法获得CPU时间。

最简单的更改方法是像下面这样添加some kind of sleep

std::thread consumingThread([&q]() {
    while (true) {
        if (!q.empty() && !isProcess2Processing) {
            consume(q.front());
            q.pop();
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }
});

您将在这里睡眠5毫秒,在此期间调度程序将能够让其他任务执行其工作。

此外,还应确保每个循环都具有退出条件,并在离开consumingThread.join();之前调用main()