2015-05-18 76 views
4

我在C++中使用構造「線程」,並在遞歸函數中創建可變數量的線程。我想讓主線等待所有這些線程。我怎樣才能做到這一點沒有WaitForMultipleObjects?等待C++中的所有線程

+4

將它們存儲在[容器](http://en.cppreference.com/w/cpp/container)中並等待它們循環?使用['std :: thread'](http://en.cppreference.com/w/cpp/thread/thread)真的沒有其他辦法。如果你想成爲便攜式和符合標準。 –

+0

我試圖把它們放在一個向量中,但是當我執行push_back方法時,Visual Studio說線程不可複製 – Seba92

+0

@ user3671840你可以使用智能指針而不是線程 - 例如'std :: vector >' –

回答

15

在cplusplus中查看example。他們用向量中的push_back()存儲線程。最後你有循環加入。

std::vector<std::thread> threads; 
//create threads 
for (int i=1; i<=10; ++i) 
    threads.push_back(std::thread(increase_global,1000)); 
//wait for them to complete 
for (auto& th : threads) 
    th.join(); 
+2

爲什麼這是downvote的原因? –

+2

不是我的投票,但它通常不如cppreference.com準確。 – MSalters

+0

同意cppreference.com是更準確的,但沒有矢量的例子 :-( –

2

我不知道你的情況的細節,但這種方法可能對你有用:

using thread_vec = std::vector<std::thread>; 

void batch_process(int n) 
{ 
    static std::mutex mtx; 
    std::lock_guard<std::mutex> lock(mtx); 
    std::cout << "process: " << n << '\n'; 
} 

void recursive(thread_vec& tv, int n) 
{ 
    // do some stuff 
    tv.emplace_back(batch_process, n); 

    if(n > 0) 
     recursive(tv, n - 1); 
} 

int main(int, char* argv[]) 
{ 
    thread_vec tv; 

    recursive(tv, 3); 

    for(auto&& t: tv) 
     t.join(); 
} 

輸出:

process: 1 
process: 0 
process: 2 
process: 3 
1

,將原子變量作爲計數器,在啓動新線程時增加變量,在線程完成後減少計數器。

int main() { 
    mutex m; 
    condition_variable cv; 
    atomic<int> counter = 0; 

    // .... in your recursive call 
    // increase counter when launching thread. 
    counter++; 
    thread t([](){ 
     // do whatever 
     lock_guard<mutex> lk(m); 
     counter--; 
     cv.notify_all(); 
    }); 
    t.detach(); // no need to join anymore. 
    // .... end recursive call 

    unique_lock<mutex> lock(m); 
    cv.wait(lock, [](){ return counter == 0; }); 
} 
+0

並將輪詢開銷(通過一些'condition_variable.wait()'實現)添加到解決方案中? – mg30rg

+4

@ mg30rg條件變量阻塞不輪詢,線程連接也阻塞。 –

1

您也可以使用boost thread_group。它僅適用於boost線程,但它們與std :: thread的接口幾乎相同(boost線程是C++ 11中標準庫中線程的基礎),並且一旦將所有線程添加到thread_group,只需在該組中調用join_all即可。你也可以實現你自己的thread_group類,與std :: thread一起工作,std :: thread會基本上完成已經建議的事情,並且使用線程對象或指針的向量,然後在循環中等待它們。