2016-06-30 28 views
18

我想將線程集合存儲在向量中,並在退出我的程序之前將它們全部加入。試圖加入的第一個線程,不管我在收集了多少地方,當我收到以下錯誤:向量中的線程無法加入

system_error: thread::join failed: No such process 

下面是一些簡單的代碼,演示了我的問題:

#include <thread> 
#include <iostream> 
#include <vector> 
#include <functional> 

using std::cout; 
using std::endl; 
using std::vector; 
using std::thread; 
using std::mem_fn; 

int main() 
{ 
    vector<thread> threads(1); 
    threads.push_back(thread([]{ cout << "Hello" << endl; })); 
    for_each(threads.begin(), threads.end(), mem_fn(&thread::join)); 

    // also tried --> for(thread &t : threads) t.join() 
} 

而且我使用以下(試過鐺++ 4.2.1和g ++ 5.3.1)構建它:

g++ -o src/thread_test.o -c -std=c++14 src/thread_test.cpp -pthread 
g++ -o thread_test src/thread_test.o -pthread 

我看到很多的例子正是這樣做這在互聯網附近。在<thread><vector>合同中是否發生了一些變化,導致這些示例失效?

注意:作爲未來讀者的預備,我在嘗試{}賦值後最終添加了(1)構造函數參數,該賦值由於私有拷貝構造函數而失敗。在試圖避免複製構造函數時,我最終分配了未初始化的線程 - 不小心的錯誤。

+1

請爲編譯和鏈接階段使用'-pthread'編譯器標誌,而不是鏈接'-lpthread'。 –

+0

我正在使用scons,所以它爲我設置了我的庫參數的格式。它實際上沒有-pthread或-lpthread,我添加它只是爲了確保在我的麻煩中不會丟失一些實現細節。所以1)我認爲編譯器爲我靜靜地添加了這些標誌,2)爲什麼非標準庫包含更好的? –

+3

'-lpthread'是對鏈接器的直接請求,而'-pthread'是編譯器驅動程序解釋的選項。如果您在編譯和鏈接時都一致地使用'-pthread',那麼編譯器驅動程序就有機會去做可能需要的任何_else_,除了在libpthread中進行鏈接以外,還可以創建一個支持多線程的程序。也就是說,我並沒有絆倒一個系統,其中許多年其他事情實際上是必要的。 – zwol

回答

33

vector<thread> threads(1);

這產生可在指數0訪問的線程。

threads.push_back(thread([]{ cout << "Hello" << endl; }));

這增加了可在指數1被訪問的第二線程。

for_each(threads.begin(), threads.end(), mem_fn(&thread::join));

這將呼籲兩國thread對象join。但是,第一個從未開始,因此它不可連接。

取而代之,您可以用vector<thread> threads; threads.reserve(1);代替vector<thread> threads(1);並繼續使用push_back