2013-04-09 41 views
3

我有一個程序多次調用std::async。執行的任務是合理的短(每個幾百毫秒)。我認爲線程創建有很大的開銷,我想知道我能否以某種方式避免這種情況。枚舉作業的代碼比作業的處理速度快得多。所以我已經有了一種合適的地方。它是這樣的。創建「的作業位置」的數組:線程池替換許多std ::異步調用

template <typename T> 
struct job { 
    std::future <void> fut; 
    std::vector <T*> *result; 
    bool inUse; 
} 

並行代碼開始之前,我初始化作業槽的陣列,從而在結果矢量只有一次。然後,每次作業枚舉代碼枚舉一個作業時,它都會查找未使用的作業插槽。如果有空閒插槽,它將啓動(使用std :: async)一個新的作業,將未來移動到插槽。作業運行並填充結果向量。如果沒有空閒時隙,則代碼檢查是否有任何時隙中的期貨已準備就緒。如果是這樣,它處理結果向量,然後使用該槽。如果不是,則等待幾毫秒。該代碼運行得非常好,並且可以根據可用處理器的數量進行擴展。我瞭解到,每次調用std::async都會創建一個新線程,實際上,我可以看到滾動的進程ID。我想消除這種開銷,在開始時一勞永逸地創建線程。如何進行?

我發現此線程池實施 https://code.google.com/p/cppthreadpool/downloads/list 但它表明,任務應該需要一兩秒鐘,這是有效的。我不需要任何花哨的調度,優先級等。我只是想刪除重複構建和線程銷燬的開銷。

+0

我跑了一個測試程序,使用std :: async創建任務,發現許多任務都是由同一個線程運行的!事實上,我看到2個線程運行20個異步任務。那麼標準庫會進行線程池嗎? – 2013-04-09 14:30:25

+0

這是什麼操作系統?我最感興趣的是Linux。你怎麼能確定使用相同的線程,而不僅僅是相同的線程ID? – Thomas 2013-04-09 14:33:51

+0

windows; VS2010;最後在期貨上等待()。 – 2013-04-09 14:39:12

回答

0

我運行了一個測試程序,使用std :: async創建任務,發現許多任務都是由同一個線程運行的!事實上,我看到2個線程運行了25個異步任務。所以看起來標準庫已經做了一些線程池。

std::vector<std::future<void>> futures; 
    for (int i = 0; i < 25; ++i) 
    { 
     auto fut = std::async([] 
     {   
      std::cout << std::this_thread::get_id() <<std::endl; 
     }); 
     futures.push_back(std::move(fut)); 
    } 
    std::for_each(futures.begin(), futures.end(), [](std::future<void> & fut) 
    { 
     fut.wait(); 
    }); 
+3

您的標準未來呼叫缺少啓動政策。運行時實現可以選擇在主線程中全部運行它們。你可以嘗試使用'std :: launch :: async'。我在Linux上,我得到25個不同的線程ID。 – Thomas 2013-04-09 14:41:50

+0

我用'std :: launch :: async'解決了25個任務的6個線程。 1:4線程:任務比例可以說 – 2013-04-09 14:47:13

+0

@AbhijitKadam:MSVC使用線程池,重用線程 – 2014-01-22 23:36:09