2016-06-30 17 views
18

Chcę przechowywać kolekcję wątków w wektorze i połączyć je wszystkie przed wyjściem z programu. Otrzymuję następujący błąd podczas próby przyłączenia się do pierwszego wątku nie ma znaczenia ile I miejsce w kolekcji:Nie można połączyć wątków w wektorze

system_error: thread::join failed: No such process 

Oto prosty kod, który pokazuje mój problem:

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

I jestem budowanie go za pomocą następującego (wypróbowany clang ++ 4.2.1 i 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 

Widzę wiele przykładów robienia tego właśnie w Internecie. Czy coś zmieniło się w umowie z <thread> lub <vector>, która sprawiła, że ​​te przykłady zostały zlikwidowane?

UWAGA: Na marginesie przyszłych czytników, doszedłem do dodania argumentu konstruktora (1) po próbie przypisania {}, co nie powiedzie się z powodu prywatnego konstruktora kopii. Próbując uniknąć konstruktora kopii, w końcu przydzieliłem niezainicjowane wątki - niedbały błąd.

+1

Proszę używać flag kompilatora '-pthread' zarówno do kompilowania, jak i łączenia, zamiast łączenia' -lpthread'. –

+0

Używam scons, więc formatuje moje argumenty biblioteczne dla mnie. Właściwie działa bez "-pthread" lub "-lpthread" i dodałem go tylko po to, aby upewnić się, że nie brakuje mi szczegółów implementacji podczas moich kłopotów. Tak 1) myślę, że kompilator dodaje dla mnie te flagi w milczeniu, i 2) dlaczego niestandardowa biblioteka zawiera preferowane? –

+3

'-lpthread' jest bezpośrednią prośbą do linkera, natomiast' -pthread' jest opcją interpretowaną przez sterownik kompilatora. Jeśli użyjesz '-pthread' konsekwentnie na czas kompilacji i łącza, to da to sterownikowi kompilatora możliwość zrobienia wszystkiego, co może być wymagane, poza połączeniem w libpthread, aby stworzyć program obsługujący wielowątkowość. To powiedziawszy, nie potknąłem się o system, w którym cokolwiek innego było rzeczywiście potrzebne przez wiele lat. – zwol

Odpowiedz

33

vector<thread> threads(1);

ten tworzy gwint, który można otworzyć w indeksie 0.

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

Dodaje drugi gwint, który można otworzyć w indeksie 1.

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

To się nazywają join obu thread obiektów. Jednak pierwszy nie został uruchomiony, dlatego nie można go dołączyć.

Zamiast tego można zastąpić vector<thread> threads(1); przez vector<thread> threads; threads.reserve(1); i nadal używać push_back.

Powiązane problemy