c++ - 在某些情况下使用阻塞处理从队列中消耗元素
问题描述
我有一个推送到队列的线程和一个消耗队列中元素的线程。其中一个元素的处理是异步的,但我不想在这个处理过程中处理其他元素。(假设输出流和队列是线程安全的)
我想知道实现消费线程的最佳方法是什么……我认为 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);
}
}
解决方案
我想知道实现消费线程的最佳方法是什么……我认为 while(true) 和条件不是最佳选择。
您在这里的考虑是有道理的:使用这样的 while 循环(即不涉及任何等待)的最大问题是您在浪费 CPU 时间和功率。您的辅助线程(以及根据您的主线程给出的代码)在一段时间内无缘无故地将 CPU 内核全部保留给自己,因此其他任务无法为自己获得 CPU 时间。
进行更改的最天真的方法是在此处添加某种类似的内容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()
。
推荐阅读
- c# - BUG:使用“eml”文件附件(通过 Outlook 互操作 API)发送的电子邮件未正确编码
- c++ - c++中多个字符串中的元音数。输入与停用词“end”一样多的字符串,输出必须是每个字符串中的元音数
- java - 有没有办法将 HttpServletRequest 转换为 PageContext
- python - 问题索引从 xml 中提取的数据
- python - playwright._impl._api_types.Error:评估失败:检索 dataLayer 变量时的循环对象值 - Playwright-Python
- r - 如何使用 taskscheduleR 自动化 R 中的脚本?
- macos - 这在汇编中意味着什么
- magento2 - 如何在 Magento 2 中创建自定义响应式导航?
- python - 在 m1 mac 上安装 SCIP
- css - Rails 应用程序,未使用 LiveReload 加载的样式