使用vector <thread>和.join()并行运行的多线程C ++程序

时间:2017-07-04 03:23:48

标签: c++ multithreading concurrency parallel-processing thread-synchronization

注意:这是我在这个网站上发表的第一篇文章,但我已经进行了广泛的搜索,但无法找到问题的解决方案。 我编写了一个程序,它基本上测试了数字向量的所有排列,以找到我定义的最佳序列。当然,即使对于小输入,计算数字的排列也非常耗时,所以我试图通过使用多线程来加快速度。

这是一个复制问题的小样本:

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%,而该程序使用的系统线程数与系统中可用的数量相同?

如果需要,我可以随时更新这篇文章。

1 个答案:

答案 0 :(得分:2)

在调试应用程序时,使用调试器来打破所有&#34;线程。然后使用调试线程窗口检查每个线程,以查看每个线程的执行位置。可能你会发现只有一个线程正在执行代码,而其余的都被阻塞在一个正在运行的线程所持有的互斥锁上。

如果您展示了更完整的代码示例,那么它可以提供很大帮助。