2016-12-29 100 views
2

我使用3個線程塊的for循環,和「數據」是一個全球性的陣列,所以我要鎖定在「calculateAll」功能的一部分,C++多線程返回值

std::vector<int> calculateAll(int ***data,std::vector<LineIndex> indexList) 
{ 
    std::vector<int> v_a=std::vector<int>(); 
    for(int a=0;a<indexList.size();a++) 
    {   
    mylock.lock(); 
    v_b.push_back(/*something related with data*/); 
    mylock.unlock(); 
    v_a.push_back(a); 
    } 
    return v_a; 
} 
for(int i=0;i<3;i++) 
    { 
     int s =firstone+i*chunk; 
     int e = ((s+chunk)<indexList.size())? (s+chunk) : indexList.size(); 
     t[i]=std::thread(calculateAll,data,indexList,s,e);  
    } 
    for (int i = 0; i < 3; ++i) 
    { 
     t[i].join(); 
    } 

我的問題是,我怎樣才能得到來自每個線程的矢量的返回值,然後將它們組合在一起?我想這樣做的原因是因爲如果我將'v_a'聲明爲全局向量,當每個線程在這個向量'v_a'中嘗試push_back它們的值時,它會有一些崩潰(或不是?)。所以我想爲每個線程聲明一個向量,然後將它們組合成一個新的向量以供進一步使用(就像我沒有線程那樣)。

或者是否有一些更好的方法來處理併發問題? 'v_a'的順序無關緊要。

我很欣賞任何建議。

+0

查找「期貨」,這是一種方式,標準規定了線程以「返回」值到另一個線程。 –

回答

3

首先,而非明確的鎖()解鎖()在代碼中看到的那樣,總是使用std::lock_guard在可能的情況。其次,你最好用std::futures這個東西。用std::async啓動每個線程,然後在另一個循環中獲得結果,同時彙總結果。就像這樣:

using Vector = std::vector<int>; 
using Future = std::future<Vector>; 
std::vector<Future> futures; 

for(int i=0;i<3;i++) 
{ 
    int s =firstone+i*chunk; 
    int e = ((s+chunk)<indexList.size())? (s+chunk) : indexList.size(); 
    auto fut = std::async(std::launch::async, calculateAll, data, indexList, s, e); 
    futures.push_back(std::move(fut));  
} 

//Combine the results 
std::vector<int> result; 
for(auto& fut : futures){ //Iterate through in the order the future was created 
    auto vec = fut.get(); //Get the result of the future 
    result.insert(result.end(), vec.begin(), vec.end()); //append it to results in order 
} 

這是基於代碼中最小的,完整的和工作的例子 - 這說明我的意思:Live On Coliru

+0

謝謝你的詳細解釋,我將嘗試這個,我漫遊使用std :: lock_guard有什麼好處? – MYtry

0

用向量和鎖創建結構。將該結構的一個實例與預先鎖定的鎖一起傳遞給每個線程。等待所有的鎖解鎖。然後每個線程完成它的工作並在完成時解鎖它的鎖。

+0

作爲評論而不是答案,這更可接受 – Alex

+1

對我來說,這似乎是一個有效的(如果不是特別詳細的)答案。 –