【问题标题】:Queueing work into a Boost Thread_Pool within a loop在循环中将工作排队到 Boost Thread_Pool
【发布时间】:2021-06-21 12:55:12
【问题描述】:

我正在尝试使用 boost thread_pool 在 while 循环中继续运行相同的函数,但遇到了一些问题。这是我的代码的 sn-p。当我运行它时,我的程序开始消耗内存,直到我的计算机没有内存为止。从调试来看,我认为这是因为队列增长得​​太快了,函数处理得不够快。我尝试将 pool.wait() 和 pool.join() 放入循环中,这适用于第一次迭代,但之后的每次迭代,它都不会等待并且工作没有被处理。

以前我使用并行 for 循环来调用我的函数,这很好用。但是随着我添加了更多需要处理的函数,我开始需要能够限制一次处理多少个函数,但我仍然希望将所有内容都排队,以便一切都完成。这就是为什么我有 6 个函数,但池大小为 4。

编辑:我想基本上将 6 个函数分批排队,并等待所有 6 个函数完成,然后再将下一组 6 个函数添加到队列中。 pool.wait() 和 pool.join() 的问题是它们设置了一个内部标志,阻止线程继续工作。而且我找不到重置此标志的方法。

driver()
{
   auto foo1 = [&](){...};
   auto foo2 = [&](){...};
   auto foo3 = [&](){...};
   auto foo4 = [&](){...};
   auto foo5 = [&](){...};
   auto foo6 = [&](){...};

   boost::asio::thread_pool pool(4);
   while(isRunning)
   {
       boost::asio::post(pool, [&foo1] {foo1(); });
       boost::asio::post(pool, [&foo2] {foo1(); });
       boost::asio::post(pool, [&foo3] {foo1(); });
       boost::asio::post(pool, [&foo4] {foo1(); });
       boost::asio::post(pool, [&foo5] {foo1(); });
       boost::asio::post(pool, [&foo6] {foo1(); });
       //boost::asio::post(pool, foo1);
       //boost::asio::post(pool, foo2);
       //boost::asio::post(pool, foo3);
       //boost::asio::post(pool, foo4);
       //boost::asio::post(pool, foo5);
       //boost::asio::post(pool, foo6);
       //pool.join();
       //pool.wait();
   }
   pool.join();
}

【问题讨论】:

    标签: c++ boost threadpool boost-asio


    【解决方案1】:

    简单的方法是在循环内重新创建池。不过,这可能会产生相当大的线程创建/关闭开销。

    因此,除此之外,您可能需要一个 fork-join 执行器。请参阅the example 或此答案:Boost asio thread_pool join does not wait for tasks to be finished

    [另外,请探索那里的问题以了解与您的情况类似的情况。]

    最后,如果你们俩

    • “我开始需要能够限制一次处理多少个函数”

    还有

    • “仍然想把所有事情都排好队,这样一切都完成了”

    您可能需要考虑将队列持久化到数据库/共享内存中,以免遇到内存限制

    【讨论】:

    • 您的第一个解决方案是一个很好的临时解决方案,而我正在查看您发布的帖子。谢谢!抱歉,我最后应该更清楚地了解我的需求。我想限制一次处理 6 个函数中的多少个,但我想将它们分批排队并等待所有 6 个完成,然后再排队下一组 6 个。我不希望它只是无限排队,因为这会导致内存问题,但 wait() 函数会阻止线程获得更多工作。
    • 啊。因此,fork-join 执行器绝对是您想要的,但您可以使用“永不过期”的deadline_time 破解它,除非您手动取消它。然后,您可以使用原子计数器进行协调,以查看它何时到达该点。这就像使用异步原语模拟barrier
    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    相关资源
    最近更新 更多