注意:这是我在这个网站上发表的第一篇文章,但我已经进行了广泛的搜索,但无法找到问题的解决方案。 我编写了一个程序,它基本上测试了数字向量的所有排列,以找到我定义的最佳序列。当然,即使对于小输入,计算数字的排列也非常耗时,所以我试图通过使用多线程来加快速度。
这是一个复制问题的小样本:
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%,而该程序使用的系统线程数与系统中可用的数量相同?
如果需要,我可以随时更新这篇文章。
答案 0 :(得分:2)
在调试应用程序时,使用调试器来打破所有&#34;线程。然后使用调试线程窗口检查每个线程,以查看每个线程的执行位置。可能你会发现只有一个线程正在执行代码,而其余的都被阻塞在一个正在运行的线程所持有的互斥锁上。
如果您展示了更完整的代码示例,那么它可以提供很大帮助。