2014-09-26 3 views
2

Кто-нибудь знает о реализации пула потоков C++, который позволяет как параллельную потоковку (как обычный пул потоков), так и позволяет выполнять обратный порядок последовательного выполнения. Я потратил несколько дней, пытаясь сделать эту работу, изменив следующие thread pool, но я не могу заставить ее работать. Я изучил методы, используемые Intel TBB, а также я изучил возможность использования концепций из PPL от Microsoft (ее асинхронная библиотека приложений выглядит многообещающей) - обе из них имеют ориентированные на задачи методы для достижения вышеуказанного. К сожалению, однако, эти решения будут не работает моя целевая PowerPC linux встроенная цель.C++ Порядок выполнения потоков в пуле потоков

EDIT я собрал живой coliru demo с источником, который производит нить график - а также показывает хороший пример scheduler_loop, где теоретически можно было бы ждать нити, чтобы закончить. В коде также показан UtlThreadPool с двумя потоками, где я передаю его с совпадающими задачами - однако это «кормление» не совсем корректно и потребует небольшой работы для прохождения через узлы.

Структура данных, которую я использую для создания графика выполнения, показана ниже. Он использует структуру данных PriorityNode. Эта структура по существу является связанным списком PriorityNodes, каждый из которых содержит вектор Задачи PriorityLevel, которые могут выполняться одновременно, и указатель на следующий PriorityNode, который указывает потоки, которые будут запускаться последовательно после этого. После того, как все они будут завершены, если член mNextNode не является nullptr, тогда это должно быть запланировано для запуска в пуле потоков (и так далее, пока mNextNode не будет иметь значение nullptr). Последовательность через этот связанный список PriorityNodes - это то, как я хочу, чтобы поток пула для последовательности через свои потоки. В PriorityNode есть оператор вставки, который обычно выводит результат следующим образом (это означало бы, что 1A1 можно запускать одновременно с 1A2, и когда оба этих потока завершили следующий PriorityNode, будут разрешены 1B1, 1B2, 1B3 и 1B4 запустить одновременно - на однако много потоков бассейн имеет в наличии

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

ближайший вещь, которую я, кажется, решение этой проблемы -. Еще раз отметим, что Intel специфичны и я при включении питания компьютера является Intel TBB - here - пример t используйте его для серийного исполнения.

/** 
* 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; 
}; 
+0

Хотя большинство пулов потоков являются эффективными для очереди задач, я не думаю, что при выполнении задач есть какие-то неотъемлемые гарантии заказа. Пул потоков обычно является тем, что управляет «независимыми рабочими элементами в фоновом режиме и параллельно». Итак, если у вас есть требования к порядку и иждивенцам, пул потоков маловероятен, что вы хотите. Я бы предложил какую-то рабочую очередь или (возможно, лучшую) структуру актера. –

+0

@PeterRitchie Я редактировал вопрос, чтобы показать живое демо. В цикле планировщика есть потенциальный заполнитель, где можно «теоретически» проверить PriorityNodes, чтобы проверить, завершены ли все PriorityNodes.mConcorrent.К сожалению, я не знаю, как это сделать. Я изучал std :: future и std :: shared фьючерсы для опроса для полного состояния нити, но он слишком продвинулся для моего уровня комфорта. – johnco3

+1

Вы можете вложить фьючерсы и что-то (включая будущее) ждать других фьючерсов с shared_future. Но, если вы хотите больше самостоятельных задач, я не уверен, что фьючерсы - это путь. –

ответ

2

Почему бы не просто использовать TBB на PowerPC? Это очень портативная библиотека, предназначенная как кросс-платформенная, так и практичная; и я слышал, что он портирован на BlueGen сообществом open-source TBB. Вы можете спросить их на форуме Intel TBB, например, путем оживления this forum thread.

Intel не распространяет PowerPC двоичных файлов для TBB, но вы можете попробовать построить его из sources просто

макияжа Т

Смотри также these community patches.

+0

Спасибо за отзыв, я неправильно предположил, что Intel TBB не будет делать код, который будет работать на конкурентных архитектурах. Теперь, когда это вариант, я рассмотрю его. – johnco3

+2

Я лично принимал участие в усилиях по переносу PowerPC, чтобы TBB мог работать на системах IBM Blue Gene, и он работал некоторое время. Я не помню точно, какой релиз впервые поддерживал его, потому что у нас была вилка какое-то время, но сегодня выпуск TBB 4.2 работает на Blue Gene/Q. – Jeff

Смежные вопросы