2016-06-30 76 views
18

Voglio memorizzare una raccolta di thread in un vettore e unirli a tutti prima di uscire dal mio programma. Ricevo il seguente errore quando si cerca di unire il primo thread non importa quante ho posto nella collezione:I thread in un vettore non possono essere uniti

system_error: thread::join failed: No such process 

Ecco qualche semplice codice che dimostra il mio problema:

#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() 
} 

E sono costruirlo usando il seguente (clang provato ++ 4.2.1 e 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 

vedo un sacco di esempi che fanno proprio questo intorno al Internet. Qualcosa è cambiato nel contratto di <thread> o <vector> che ha reso questi esempi defunti?

NOTA: A parte i futuri lettori, ho finito per aggiungere l'argomento del costruttore (1) dopo aver provato l'assegnazione {}, che non riesce a causa di un costruttore di copia privata. Nel tentativo di evitare il costruttore di copie ho finito per allocare i thread non inizializzati - errore incurante.

+1

Si prega di utilizzare i flag del compilatore '-pthread' sia per la fase di compilazione che di collegamento, piuttosto che per il collegamento di' -lpthread'. –

+0

Sto usando scons, quindi formatta gli argomenti della mia libreria per me. In realtà funziona senza o-pthread o -lpthread e l'ho aggiunto solo per assicurarmi che non mi mancassero alcuni dettagli di implementazione durante i miei problemi. Quindi 1) penso che il compilatore stia aggiungendo quelle bandiere per me in silenzio, e 2) perché è preferibile includere la lib non standard? –

+3

'-lpthread' è una richiesta diretta al linker mentre' -pthread' è un'opzione interpretata dal driver del compilatore. Se si usa '-pthread' coerentemente sia in fase di compilazione che di collegamento, ciò dà al driver del compilatore l'opportunità di fare qualsiasi cosa _else_ che possa essere richiesta, oltre al collegamento in libpthread, per creare un programma capace di multithread. Detto questo, non sono inciampato in un sistema in cui qualsiasi altra cosa era effettivamente necessaria in molti anni. – zwol

risposta

33

vector<thread> threads(1);

Questo crea un filo che può essere letta in dell'indice 0.

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

Questo aggiunge un secondo filo che può essere letta in dell'indice 1.

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

questo sta andando a chiamare join su entrambi thread oggetti. Tuttavia, il primo non è mai stato avviato, quindi non è univoco.

Invece, è possibile sostituire vector<thread> threads(1); con vector<thread> threads; threads.reserve(1); e continuare a utilizzare push_back.

Problemi correlati