[英]C++ Thread execution order in a thread pool
有誰知道 C++ 線程池實現,它既允許並行線程(如典型的線程池),又允許背靠背串行執行順序。 我花了幾天時間試圖通過修改以下 線程池來完成這項工作,但我似乎無法讓它工作。 我研究了英特爾 TBB 使用的技術,也研究了可能使用微軟 PPL 的概念(它的異步代理庫看起來很有希望)——兩者都有面向任務的技術來實現上述目標——不幸的是,這些解決方案將不工作我的目標 PowerPC linux 嵌入式目標。
編輯我將一個實時的coliru演示與生成線程圖的源代碼放在一起 - 並且還展示了一個很好的scheduler_loop示例,理論上可以等待線程完成。 該代碼還顯示了一個帶有 2 個線程的 UtlThreadPool,我在其中向它提供並發任務 - 但是“饋送”並不完全正確,需要做一些工作才能遍歷節點。
我用來制作執行圖的數據結構如下所示。 它使用PriorityNode數據結構。 這個結構本質上是一個 PriorityNode 的鏈表,每一個都包含一個可以並發運行的PriorityLevel任務向量和一個指向下一個 PriorityNode 的指針,該指針指示之后要串行運行的線程。 一旦這些都完成了,如果 mNextNode 成員不是 nullptr,那么這應該被安排在線程池中運行(依此類推,直到 mNextNode 為 nullptr。通過這個 PriorityNodes 鏈表進行排序是我想要線程的方式池以通過其線程進行排序。PriorityNode 具有插入運算符,通常會產生如下輸出。(這意味着 1A1 可以與 1A2 並發運行,當這兩個線程都完成后,下一個 PriorityNode 將允許 1B1、1B2、1B3 和1B4 並發運行 - 無論池中有多少線程可用。
1A1
1A2
+-1B1
+-1B2
+-1B3
+-1B4
我似乎解決這個問題的最接近的東西 - 再次注意它是特定於英特爾的,我在電源 PC 上是英特爾 TBB - 這是他們用於串行執行順序的示例。
/**
* 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;
};
如果有人仍在尋找這個,請查看這里的 repo - 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;
});
}
它將按順序執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.