C ++线程池中的线程执行顺序

时间:2014-09-26 16:43:28

标签: c++ c++11 threadpool tbb ppl

有没有人知道C ++线程池实现允许并行线程(如典型的线程池),但也允许背靠背串行执行顺序。我花了几天时间通过修改以下thread pool来尝试完成这项工作,但我似乎无法使其工作。我已经研究了intel TBB使用的技术,我也研究了可能使用微软PPL的概念(它的异步代理库看起来很有希望) - 两者都有面向任务的技术来实现上述目标 - 不幸的是,这些解决方案将会不能正常工作我的目标PowerPC linux嵌入式目标。

编辑我将一个实时的 coliru demo 与生成线程图的源码放在一起 - 并且还显示了一个很好的scheduler_loop示例,理论上可以等待线程完成。该代码还显示了一个带有2个线程的UtlThreadPool,我在其中提供了concurent任务 - 但是'喂养'并不完全正确,需要一些工作来遍历节点。

我用来制作执行图的数据结构如下所示。它使用 PriorityNode 数据结构。此结构本质上是PriorityNodes的链接列表,每个都包含可以并发运行的 PriorityLevel 任务的向量和指向下一个PriorityNode的指针,该指针指示之后串行运行的线程。一旦这些完成ALL,如果mNextNode成员不是nullptr,那么这应该被安排在线程池中运行(等等直到mNextNode为nullptr。通过这个PriorityNodes的链接列表排序是我想要的线程通过其线程对池进行排序.PriorityNode具有插入操作符,通常按如下方式生成输出。(这意味着1A1可以与1A2同时运行,当这两个线程都完成后,下一个PriorityNode将允许1B1,1B2,1B3和1B4同时运行 - 无论池有多少线程可用。

1A1
1A2
+-1B1
+-1B2
+-1B3
+-1B4

我最接近的问题似乎解决了这个问题 - 再次注意它是特定于英特尔的,我在电源PC上是英特尔TBB - here是他们用于串行执行命令的例子。

/**
 * Branch representing fundamental building block of
 * a priority tree containing szPriority entries.<p>
 *
 * Each priority tree struct contains a vector of concurrent
 * priorities that can be scheduled to run in the thread pool -
 * note that the thread pool must have no entries associated
 * with the current channel running before enqueueing these
 * tasks. The application must wait for the thread pool to
 * complete these tasks before queuing up the dependent tasks
 * described in the mNextNode smart pointer. If mNextNode is
 * unassigned (nullptr), then we have reached the end of the
 * tree.
 */
struct PriorityNode {
    explicit PriorityNode(
        const std::vector<PriorityLevel>& rConcurrent,
        const std::shared_ptr<PriorityNode>& rNext = std::shared_ptr<PriorityNode>(),
        const size_t& rDepth = 0)
        : mConcurrent(rConcurrent)
        , mNextNode(rNext)
        , mDepth(rDepth)
    {}

    /**
    * Stream insert operator<p>
    *
    * @param os     [in,out] output stream
    * @param rhs    [in] PriorityLevel to send to the output
    *               stream.
    *
    * @return a reference to the updated stream
    */
    inline friend std::ostream& operator << (
        std::ostream& os, const PriorityNode& rhs) {
        // indent 2 spaces per depth level
        std::string indent = rhs.mDepth > 0 ?
            (std::string("+") +
            std::string((rhs.mDepth * 2) - 1, '-')) :
            std::string();
        // print out the concurrent threads that 
        // can be scheduled with the thread pool
        for (const auto& next : rhs.mConcurrent) {
            os << indent << next << std::endl;
        }
        // print the dependent priorities that can only
        // be scheduled when the concurrent ones are finished
        if (rhs.mNextNode) {
            os << *rhs.mNextNode << std::endl;
        }
        return os;
    }
    // these are all equivalent thread priorities
    // that can be run simultaneously
    std::vector<PriorityLevel> mConcurrent;

    // these are concurrent threads that must be AFTER all 
    // mConcurrent tasks have completed (exiting the thread pool)
    std::shared_ptr<PriorityNode> mNextNode;

    // recursion depth
    size_t mDepth;
};

2 个答案:

答案 0 :(得分:2)

为什么不在PowerPC上使用TBB?它是一个高度可移植的库,旨在实现跨平台;而且我听说TBB开源社区将它移植到BlueGen上。您可以在英特尔TBB论坛上询问他们,例如,通过恢复this forum thread

英特尔不为TBB分发PowerPC二进制文件,但您可以尝试从sources简单地通过

构建它
  

制作tbb

另见these community patches

答案 1 :(得分:0)

如果有人仍在寻找此商品,请在此处查看回购-https://github.com/hirak99/ordered_thread_pool

基本上,您可以替换这样的代码-

while (...) {
  std::cout << CostlyFn(input)) << std::endl;
}

进入-

OrderedThredPool<std::string> pool{10, 1};
while (...) {
  pool.Do(
    [&input] { return CostlyFn(input); },
    [](const std::string& out) {
      std::cout << out << std::endl;
    });
}

它将按顺序执行。

相关问题