首页 文章

提升线程池

提问于
浏览
2

我的应用程序需要一个线程池,我希望尽可能依赖标准(C 11或boost) . 我意识到有一个非官方的(!)提升线程池类,它基本上解决了我需要的东西,但是我宁愿避免它,因为它不在boost库本身 - 为什么它仍然不在核心库之后很多年?

在本页和其他地方的一些帖子中,人们建议使用boost :: asio来实现类似行为的线程池 . 乍一看,这看起来像我想要做的,但是我发现我看到的所有实现都无法加入当前活动的任务,这使得它对我的应用程序毫无用处 . 为了执行连接,它们向所有线程发送停止信号,然后加入它们 . 但是,这完全消除了我的用例中线程池的优势,因为这使得新任务需要创建新线程 .

我想做的是:

ThreadPool pool(4);
for (...)
{
    for (int i=0;i<something;i++)
        pool.pushTask(...);
    pool.join();
    // do something with the results
}

任何人都可以建议一个解决方案(除了在sourceforge上使用现有的非官方线程池)? C 11或核心提升中有什么可以帮助我吗?

4 回答

  • 0

    乍一看,这看起来像我想要做的,但是我发现我看到的所有实现都没有办法加入当前活动的任务,这使得它对我的应用程序毫无用处 . 为了执行连接,它们向所有线程发送停止信号,然后加入它们 . 但是,这完全消除了我的用例中线程池的优势,因为这使得新任务需要创建新线程 .

    我想你可能误解了asio的例子:

    IIRC(并且已经有一段时间了)在线程池中运行的每个线程都调用了 io_service::run ,这意味着每个线程实际上都有一个事件循环和一个调度程序 . 然后让asio完成任务,你使用io_service :: post方法将任务发布到 io_service ,并且asio 's scheduling mechanism takes care of the rest. As long as you don't调用 io_service::stop ,线程池将继续使用你开始运行的线程运行(假设每个线程都有工作要做)或者已经分配了 io_service::work 对象) .

    因此,您不需要为新任务创建新线程,这将违背线程池的概念 .

  • 1

    让每个任务类派生自具有“OnCompletion(task)”方法/事件的Task . 然后,线程池线程可以在调用任务的主run()方法之后调用它 .

    等待单个任务完成就很容易了 . OnCompletion()可以执行发信号通知始发线程所需的任何信号,发出condvar信号,将任务排队到 生产环境 者 - 消费者队列,调用SendMessage / PostMessage API,Invoke / BeginInvoke等等 .

    如果一个oringinating线程需要等待几个任务完成,你可以扩展上面的内容并向池发出一个“Wait task” . 等待任务有自己的OnCompletion来传达其他任务的完成,并具有线程安全的“任务计数器”(原子操作或锁定),设置为要发出的“主要”任务的数量 . 等待任务首先发送到池,并且运行它的线程在等待任务中的私有'allDone'condvar上等待 . 然后,将'main'任务发送到池中,并将其OnCompletion设置为调用等待任务的方法,该方法将任务计数器递减为零 . 当任务计数器达到零时,实现此功能的线程将发出allDone condvar信号 . 等待任务OnCompletion然后运行,因此表示所有主要任务的完成 .

    这种机制不需要连续创建/终止/加入/删除线程池线程,不需要如何发信号通知原始任务,您可以根据需要发出任意数量的此类任务组 . 但是,您应该注意,每个等待任务都会阻塞一个线程池线程,因此请确保在池中创建一些额外的线程(通常不会出现任何问题) .

  • 3

    这似乎是boost::futures的工作 . 文档中的示例似乎准确地证明了您要做的事情 .

  • 1

    加入一个线程意味着停止它直到它停止,如果它停止并且你想为它分配一个新任务,你必须创建一个新线程 . 因此,在您的情况下,您应该等待一个条件(例如 boost::condition_variable )来指示任务结束 . 因此,使用这种技术很容易使用 boost::asioboost::condition_variable 来实现它 . 每个线程调用 boost::asio::io_service::run 和任务将在不同的线程上进行调度和执行,最后,每个任务都会设置一个 boost::condition_variable 或事件递减 std::atomic 以指示作业结束!那个's really easy, isn't呢?

相关问题