2013-04-14 8 views
9

Zgodnie z dokumentacją here i here, metoda łączenia wątku C++ 11 rzuci std::system_error jeśli joinable() == false. Tak więc w naturalny sposób czekać na wątku do zakończenia realizacji jest coś wzdłuż linii:C++ 11 bezpiecznie dołącz do wątku bez użycia bloku próbnego/przechwytywania

if (thread2.joinable()) thread2.join(); 

to jednak ma możliwość rzucić std :: system_error. Rozważmy wątek 1 wywołuje thread2.joinable(), zwraca true, wskazując, że wątek2 nadal działa. Następnie program planujący zatrzymuje wątek1 i przełącza konteksty na wątek 2. Wątek 2 kończy działanie, a następnie wątek 1 wznawia. Wątek 1 wywołuje thread2.join(), ale wątek2 został już zakończony, w wyniku czego generowany jest komunikat std :: system_error.

Możliwym rozwiązaniem jest zawinąć całość w bloku try:

try { 
    thread2.join(); 
catch (std::system_error &e) {} 

Ale wtedy, gdy uzasadniony std :: system_error jest wyrzucane, może wskazywać, że wątek udało się przyłączyć, z Program trwa dalej, zachowując się tak, jakby wszystko było w porządku i dandys. Czy istnieje odpowiedni sposób na dołączenie do wątku oprócz tego, że używa się bloku try/catch?

Odpowiedz

10

joinable nie robi to, co myślisz, że robi. Wszystko, co robi, to czy obiekt wątku nie jest powiązany z wątkiem. Jednakże, thread::join zakończy się niepowodzeniem, jeśli obiekt wątku reprezentuje również bieżący wątek. Dlatego jedynym powodem, dla którego thread::join zawodzi z powodu braku numeru joinable, jest próba połączenia się z samym sobą.

Zakończonywątek (który nie należy do Ciebie) jest nadal doskonale łączony.

+3

'joinable' również zwróci' false' jeśli wątek zostanie odłączony. –

+1

@Adam: Dzięki za wyjaśnienie, co naprawdę oznacza "niezwiązany z nicią". –

+1

'zwraca, czy obiekt wątku reprezentuje bieżący wątek, czy nie jest powiązany z wątkiem' [joinable] (http://en.cppreference.com/w/cpp/thread/thread/joinable) sprawdza ** tylko skojarzenie ** z wątkiem, ale nie z bieżącym wątkiem. ** Ale ** [dołącz] (http://en.cppreference.com/w/cpp/thread/thread/join) sprawdzi bieżący wątek i zgłosi "system_error". [live] (http://coliru.stacked-crooked.com/a/422f27866296efd0) example. –

Powiązane problemy