2013-03-01 3 views
21

Con definition from C++ reference:Cosa fa std :: thread.join()?

Blocca il thread corrente finché il filo identificato dal *this termina la sua esecuzione.

Quindi questo significa quando si utilizza .join(), non c'è alcun bisogno di mutex.lock() quando quel thread chiama qualche funzione? Sono nuovo di mutua esclusione e threading, quindi sono un po 'confuso.

Nota: ho trovato un libro Concorrenza in C++ e sto leggendo il libro. È scritto molto bene per un principiante nel multithreading come me.

Grazie a tutti per l'aiuto.

+3

Grazie David per il montaggio per renderlo più chiaro. Martin: Ho provato a google ma ho visto 4-5 campioni che hanno avuto la stessa idea e non mostra realmente ciò che il join sta facendo dal mio punto di vista..Penso che ppl qui sia ben informato e fornirebbe le migliori risposte con il codice campioni. – Guagua

risposta

17

Hai ancora bisogno di mutex e condizioni. Unire un thread fa sì che un thread di esecuzione attenda che un altro thread finisca di funzionare. Hai ancora bisogno di mutex per proteggere le risorse condivise. Permette a main() in questo esempio di aspettare che tutti i thread finiscano prima di abbandonare se stesso.

#include <iostream> 
#include <thread> 
#include <chrono> 
#include <mutex> 

using namespace std; 



int global_counter = 0; 
std::mutex counter_mutex; 

void five_thread_fn(){ 
    for(int i = 0; i<5; i++){ 
     counter_mutex.lock(); 
     global_counter++; 
     counter_mutex.unlock(); 
     std::cout << "Updated from five_thread" << endl; 
     std::this_thread::sleep_for(std::chrono::seconds(5)); 
    } 
    //When this thread finishes we wait for it to join 
} 

void ten_thread_fn(){ 
    for(int i = 0; i<10; i++){ 
     counter_mutex.lock(); 
     global_counter++; 
     counter_mutex.unlock(); 
     std::cout << "Updated from ten_thread" << endl; 
     std::this_thread::sleep_for(std::chrono::seconds(1)); 
    } 
    //When this thread finishes we wait for it to join 
} 
int main(int argc, char *argv[]) { 
    std::cout << "starting thread ten..." << std::endl; 
    std::thread ten_thread(ten_thread_fn); 

    std::cout << "Running ten thread" << endl; 
    std::thread five_thread(five_thread_fn); 


    ten_thread.join(); 
    std::cout << "Ten Thread is done." << std::endl; 
    five_thread.join(); 
    std::cout << "Five Thread is done." << std::endl; 
} 

nota che l'output potrebbe essere simile a questo:

starting thread ten... 
Running ten thread 
Updated frUopmd atteend_ tfhrroema df 
ive_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from five_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from ten_thread 
Updated from five_thread 
Ten Thread is done. 
Updated from five_thread 
Updated from five_thread 
Five Thread is done. 

Dal std :: cout è un accesso alle risorse condivise e uso di esso dovrebbe anche essere mutex protetto troppo.

+1

Grazie Joel, quindi qui ten_thread.join() dirà che il programma ten_thread è terminato e può andare al passaggio successivo? – Guagua

+1

il thread di esecuzione che esegue main() si bloccherà alla chiamata di ten_thread.join() fino a che non viene restituito dieci_thread. Una volta che l'esecuzione di ten_thread termina, l'esecuzione di main è consentita. Spero che questo ti aiuti. – Joel

6

join() interrompe il thread corrente fino a quando non ne termina un'altra. mutex interrompe il thread corrente fino a quando il proprietario mutex lo rilascia o blocca immediatamente se non è bloccato. Quindi questi ragazzi sono abbastanza diversi

+6

Preferisco "sospendere" invece di "fermate", però. – Sebastian

0

std :: Thread.join ha tre funzioni posso pensare off-mano e alcuni altri:

a) incoraggia continuo creazione/terminazione/distruzione di fili, così martellare prestazioni e aumentare la probabilty di perdite, thread-runaway, memory-funaway e generale perdita di controllo della tua app.

b) Stuffa i gestori di eventi GUI imponendo attese indesiderate, con conseguente 'app clessidra' che i tuoi clienti odieranno.

c) Le app non vengono arrestate perché sono in attesa della chiusura di un thread non reversibile e non interrompibile.

d) Altre cose cattive.

Capisco che siete nuovi al multithreading e vi auguro il meglio. Inoltre, considera che ho avuto un sacco di Adnams Broadside stasera, ma:

Join(), e sono amici in altri linguaggi come TThread.WaitFor, (Delphi), sono a multithreading efficiente come Windows ME era quello di operare sistemi.

Si prega di provare a progredire e comprendere altri concetti multithread: pool, attività, thread di app-lifetime, comunicazioni tra thread tramite code produttore-consumatore. In effetti, quasi tutto tranne Join().

+3

Ciao Martin, qualsiasi lettura consigliata sul multithreading in C++? – Guagua

1

Blocca il thread corrente fino al completamento dell'esecuzione del thread su cui viene chiamato join().

Se non si specifica join() o dettach() sul thread, si verificherà un errore di runtime in quanto il thread principale/corrente completerà l'esecuzione e l'altro thread creato sarà ancora in esecuzione.