簡體   English   中英

另一個線程完成后立即產生一個新線程

[英]Spawn a new thread as soon as another has finished

我有一個昂貴的函數,需要執行1000次。 執行可能需要5到10分鍾。 因此,它具有很大的變化。 我喜歡有多個線程在處理它。 我當前的實現將這1000個調用設計為4個250個調用,並產生4個線程。 但是,如果一個線程有“糟糕的一天”,那么與其他三個線程相比,完成時間要長得多。

因此,無論何時線程完成上一個調用,我都希望對該函數進行新的調用-直到完成所有1000次調用為止。

我認為線程池可以工作-但如果可能,我希望有一個簡單的方法(=盡可能少的附加代碼)。 基於任務的設計也朝這個方向發展(我認為)。 有一個簡單的解決方案嗎?

用1000個單位初始化信號量。 讓4個線程中的每一個都圍繞信號量wait()和work函數循環。

然后,所有線程將對該函數起作用,直到執行了1000次為止。 即使其中三個線程卡住並花了很多時間,第四個仍將處理其他997個調用。

[編輯]另外,標准C ++ 11庫不包含信號燈。 但是,信號量是基本的操作系統sunchro原語,因此應該足夠容易調用,例如。 與POSIX。

假設您已經能夠將調用划分為單獨的實體和要處理的線程。 一種方法是使用std::package_task (及其關聯的std::future )來處理函數調用,並將它們放在某種隊列中。 反過來,每個線程都可以提取打包的任務並對其進行處理。

您將需要鎖定隊列以進行並發訪問,這里可能會有一些瓶頸,但是與線程可能會遇到“糟糕的一天”的擔憂相比,這應該很小。 這實際上是一個線程池,但是它使您可以控制任務的執行。

另一種選擇是使用std::async並將其啟動策略指定std::launch::async ,其缺點是您不控制線程本身的創建,因此取決於標准庫控制線程的效率。與您擁有多少個核心。

無論哪種方法都行得通,關鍵是要在合理的樣本量下衡量這些方法的效果。 該措施應用於時間和資源使用(線程和保持內核繁忙)。 大多數操作系統將包括衡量流程資源使用情況的方法。

您可以使用Exectuors的參考實現之一,然后通過調用函數

#include <experimental/thread_pool>

using std::experimental::post;
using std::experimental::thread_pool;

thread_pool pool_{1};

void do_big_task()
{
    for (auto i : n)
    {
        post(pool_, [=]
        {
            // do your work here;
        });
    }
}

執行程序使用C ++ 17編寫,所以我想我會早一點。

或者,如果您想嘗試另一種執行程序,則可以使用語法稍有不同的最新實現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM