另一个完成后立即生成一个新线程

时间:2016-02-14 16:29:58

标签: c++ multithreading c++11

我需要执行1000次昂贵的功能。执行可能需要5秒到10分钟。因此它具有很大的变化。 我喜欢有多个线程在上面工作。我目前的实现是在250次调用中设计了这1000次调用,并产生了4个线程。但是,如果一个线程有一个"糟糕的一天",与其他3个线程相比,它的完成时间要长得多。

因此,每当线程完成上一次调用时,我都希望对该函数进行新的调用 - 直到完成所有1000次调用。

我认为线程池可以工作 - 但是如果可能的话,我希望有一个简单的方法(=尽可能减少额外的代码)。基于任务的设计也朝这个方向发展(我认为)。对此有一个简单的解决方案吗?

3 个答案:

答案 0 :(得分:2)

初始化1000个单位的信号量。让4个线程中的每一个都绕着信号量wait()和工作函数循环。

然后,所有线程将对该函数起作用,直到它被执行了1000次。即使其中三个线程卡住并且需要很长时间,第四个线程也会处理其他997个呼叫。

[编辑] 嗯..一般来说,标准的C ++ 11库不包含信号量。但是,信号量是一个基本的OS sunchro原语,所以应该很容易调用,例如。与POSIX。

答案 1 :(得分:0)

鉴于您已经能够将调用分段为单独的实体和要处理的线程。一旦方法是使用std::package_task(及其关联的std::future)来处理函数调用,并将它们放在某种队列中。反过来,每个线程都可以获取打包的任务并进行处理。

你需要锁定队列以进行并发访问,这里可能存在一些瓶颈,但与线程可能会有一个糟糕的日子相关的问题相比,这应该是最小的。这实际上是一个线程池,但它允许您控制任务的执行。

另一个替代方法是使用std::async并指定其launch policy as std::launch::async,缺点是您不能控制线程创建本身,因此您依赖于标准库控制线程vs的效率你有多少核心。

任何一种方法都可行,关键是在合理的样本量上测量方法的性能。措施应该是时间和资源使用(线程和保持核心繁忙)。大多数操作系统将包括测量过程资源使用情况的方法。

答案 2 :(得分:0)

您可以使用Exectuors的任一参考实现,然后通过

调用该函数
#include <experimental/thread_pool>

using std::experimental::post;
using std::experimental::thread_pool;

thread_pool pool_{1};

void do_big_task()
{
    for (auto i : n)
    {
        post(pool_, [=]
        {
            // do your work here;
        });
    }
}

执行者正在使用C ++ 17,所以我想我会早点进入。

或者,如果您想尝试另一种执行程序,那么more recent implementation的语法略有不同。