我有一个线程推送到队列,另一个线程消耗队列中的元素。 其中一个元素的处理是异步的,但是在此过程中,我不想处理其他元素。 (假设输出流和队列是线程安全的)
我想知道实现消耗线程的最佳方法是什么...我认为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);
}
}
答案 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()
。