【发布时间】:2020-04-04 13:27:51
【问题描述】:
我想知道在使用 lambda 表达式来定义线程时,它是否有助于提高一些性能增益。就我而言,我必须运行多个线程。这是基于实时的应用程序。因此,如果有人向我建议创建多个线程的最佳方式是什么。创建线程发生在实际代码库的每次迭代中。这是高级迭代中发生的事情的一个示例。因此,这是一种需要优化的昂贵操作。
#include <iostream>
#include <thread>
#include <vector>
#include <algorithm>
class Task
{
public:
void execute(std::string command)
{
//TODO actual logic
for(int i = 0; i < 5; i++)
{
std::cout<<command<<std::endl;
}
}
};
int main()
{
Task* taskPtr = new Task();
std::vector<std::thread> workers_older;
for (int i = 0; i < 2; i++) {
workers_older.push_back(std::thread(&Task::execute, taskPtr, "Task: without lambda expression"+ std::to_string(i)));
}
std::for_each(workers_older.begin(), workers_older.end(), [](std::thread &t)
{
t.join();
});
std::vector<std::thread> workers;
for (int i = 0; i < 2; i++) {
workers.push_back(std::thread([&]()
{
taskPtr->execute("Task: "+ std::to_string(i));
}));
}
std::for_each(workers.begin(), workers.end(), [](std::thread &t)
{
t.join();
});
return 0;
}
编辑: 在关于要做什么的宝贵意见之后,我已经按照他们的建议提供了答案
【问题讨论】:
-
如果 lambda 有所作为,我会感到非常惊讶。但我鼓励你衡量它。一种解决方案是拥有一个工人池,而不是每次都产生一个线程。然而,性能增益(或损失)完全取决于你真正在做什么。原因很明显,在您向我们展示的代码中,使用池会降低性能(因为您只有 4 个任务要处理)。
-
很难给你一个明确的答案,平台会影响结果,我建议你在profiler中尝试不同的解决方案。话虽如此,我会假设启动线程、上下文切换和其他线程内容将完全超过使用 lambda 或将参数直接发送到
std::thread构造函数的差异。 -
每次迭代都会创建线程?这些迭代在哪里?
-
由于您担心线程创建的成本(您这样做是对的!),您可能希望重用线程。也许您正在寻找类似线程池的东西stackoverflow.com/questions/26516683/reusing-thread-in-loop-c。
-
OT:为什么不简单地
for (auto& t : workers) t.join();?另外,return 0;在main中是多余的。
标签: c++ multithreading performance c++11