注意:这是我在此网站上发表的第一篇文章,但我进行了大量搜索,但无法找到解决我的问题的方法。 我编写了一个程序,它本质上测试了数字 vector 的所有排列,以找到我定义的最佳序列。当然,即使对于小输入,计算数字排列也非常耗时,因此我尝试通过使用多线程来加快速度。
这是一个复制问题的小样本:
class TaskObject {
public:
void operator()() {
recursiveFunc();
}
private:
Solution *bestSolution; //Shared by every TaskObject, but can only be accessed by one at a time
void recursiveFunc() {
if (base_case) {
//Only part where shared object is accessed
//base_case is rarely reached
return;
}
recursiveFunc();
}
};
void runSolutionWithThreads() {
vector<thread> threads(std::thread::hardware_concurrency());
vector<TaskObject> tasks_vector(std::thread::hardware_concurrency());
updateTasks(); //Sets parameters that intialize the first call to recursiveFunc
for (int q = 0; q < (int)tasks_vector.size(); ++q) {
threads[q] = std::thread(tasks_vector[q]);
}
for (int i = 0; i < (int)threads.size(); ++i) {
threads[i].join();
}
}
我以为这将使所有线程能够并行运行,但我可以在 Visual Studio 中使用性能分析器以及 Windows 任务管理器的高级设置中看到,一次只有 1 个线程运行。在可访问 4 个线程的系统上,CPU 利用率被限制在 25%。 每次运行我都会得到正确的输出,因此算法逻辑没有问题。工作尽可能均匀地分布在所有任务对象之间。与共享数据的冲突很少发生。使用线程池实现的程序始终以接近 100% 的速度运行。
提交给线程的对象不会打印到 cout,并且除了它们都通过指针引用的一个共享对象外,所有对象都有自己执行其工作所需的数据拷贝。
private:
Solution* bestSolution;
此共享数据不易受到数据竞争条件的影响,因为我使用互斥体中的 lock_guard 来制作它,因此一次只有一个线程可以更新 bestSolution。
换句话说,为什么我的多线程程序的 CPU 没有以接近 100% 的速度运行,而该程序使用了系统中可用的尽可能多的线程?
如果需要,我可以随时用更多信息更新这篇文章。
最佳答案
在调试应用程序时,使用调试器“中断所有”线程。然后使用调试线程窗口检查每个线程以查看每个线程正在执行的位置。您可能会发现只有一个线程正在执行代码,而其余线程都被一个正在运行的线程持有的互斥体阻塞。
如果您展示更完整的代码示例,它会很有帮助。
关于c++ - 多线程 C++ 程序未使用 vector<thread> 和 .join() 并行运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44896500/