Come si stacca un thread in C++?

Come si stacca un thread in C++?
Un thread si stacca da cosa? - Un thread si stacca da un join. La domanda successiva è "Ciò che è un join?" - Invece di avere un programma di dichiarazioni in esecuzione dall'inizio alla fine, in sequenza, il programma può essere raggruppato in sezioni speciali di dichiarazioni. Le sezioni speciali sono chiamate thread, che possono quindi funzionare in parallelo o contemporaneamente. Per convertire una serie di dichiarazioni in un thread, è necessaria una codifica speciale. Sfortunatamente, i thread in C ++ sarebbero eseguiti in modo indipendente se non fossero uniti. In tale situazione, un secondo thread può finire dopo che il thread principale è terminato. Questo di solito non è desiderabile.

Perché ci sia qualsiasi unione, sono necessari due thread. Un thread chiama l'altro thread. Unirsi a un thread significa che, mentre il thread chiamante è in esecuzione, si fermerebbe in una posizione e attendere che il thread chiamato completasse la sua esecuzione (fino alla sua fine), prima che continui la propria esecuzione. Nella posizione in cui si ferma il filo, c'è un'espressione di join. Tale arresto si chiama blocco.

Se il thread chiamato sta impiegando troppo tempo per essere completato e probabilmente ha fatto ciò che il thread chiamante si aspettava che facesse, allora il thread chiamante può staccarlo. Dopo il distacco, se il thread chiamato si completa dopo il thread chiamante, non ci dovrebbero essere problemi. Distacco significa rompere il join (link).

Richiamare

Un thread è una funzione di livello superiore che è stata racchiusa in un oggetto thread, istanziata dalla classe thread. Istanziando il thread con la funzione di livello superiore significa chiamare la funzione. Ecco un semplice programma di thread, con l'istruzione join:

#includere
#includere
Utilizzo dello spazio dei nomi std;
void func ()
cout <<"… from thread!" <<'\n';

int main ()

Thread Thd (func);
Thd.giuntura();
/ * dichiarazioni */
restituzione 0;

Ci sono due thread qui: l'oggetto, THD e la funzione principale (). La funzione principale è come il filo principale. Nota l'inclusione della libreria di thread. L'output è:

... dal thread!

Nel prompt dei comandi, un programma C ++ 20 con thread, dovrebbe essere comandato come segue, per il compilatore G ++:

g ++ -std = c ++ 2a campione.cc -lpthread -o campione.exe

Contenuto dell'articolo

  • Sintassi Detach ()
  • Nome del thread a Global Scope
  • Distacco all'interno del thread chiamato
  • Conclusione

Sintassi Detach ()

La sintassi di Detach () è semplice; è:

Discussione.detach ()

Questa funzione membro dell'oggetto thread restituisce vuoto. threadobject è l'oggetto thread del thread la cui funzione è in esecuzione. Quando la funzione di un thread è in esecuzione, il thread viene chiamato thread di esecuzione.

Un thread può essere staccato solo dopo che è stato unito; Altrimenti, il thread è già nello stato distaccato.

Ambiguità del distacco nel corpo del thread chiamante

Nel seguente programma, il thread chiamato viene staccato nel corpo del thread chiamante:

#includere
#includere
#includere
Utilizzo dello spazio dei nomi std;
String Globl = String ("Sulla terra!");
void func (string st)
String fin = "Living" + St;
cout <
int main ()

Thread Thr (func, Globl);
thr.giuntura();
thr.detach ();
restituzione 0;

L'output dal computer dell'autore in fase di esecuzione era:

Vivere sulla terra!
terminare chiamato dopo aver lanciato un'istanza di "std :: system_error"
Cosa (): argomento non valido
Abortito (core scaricato)

L'output corretto previsto dovrebbe essere giusto:

Vivere sulla terra!

Quando un thread termina la sua esecuzione, l'implementazione rilascia tutte le risorse che possedeva. Quando viene unito un thread, il corpo del thread chiamante attende a quel punto fino a quando il thread chiamato completa la sua esecuzione, il corpo del thread chiamante continua la propria esecuzione.

Il problema della presenza dell'ulteriore output è che sebbene il thread chiamato potesse aver completato il suo compito assegnato, le sue risorse non erano state tutte portate via, ma la funzione di detach () ha causato l'esecuzione del corpo della funzione chiamante. In assenza della funzione Detach (), il thread chiamato avrebbe completato, oltre a tutte le sue risorse portate via; e l'output sarebbe stato il semplice previsto.

Per convincere ulteriormente il lettore, considera il seguente programma, che è lo stesso di quanto sopra, ma con le dichiarazioni di join () e detach () commentate:

#includere
#includere
#includere
Utilizzo dello spazio dei nomi std;
String Globl = String ("Sulla terra!");
void func (string st)
String fin = "Living" + St;
cout <
int main ()

Thread Thr (func, Globl);
// Thr.giuntura();
// Thr.detach ();
restituzione 0;

L'output dal computer dell'autore è:

terminare chiamato senza un'eccezione attiva
Abortito (core scaricato)

La funzione principale () è passata fino alla fine senza aspettare che il thread faccia qualcosa. E così, il thread non ha potuto visualizzare il suo output.

Nome del thread a Global Scope

Un thread può essere istanziato all'ambito globale. Il seguente programma illustra questo:

#includere
#includere
Utilizzo dello spazio dei nomi std;
Discussione Thr;
void func ()
cout <<"the first line" <cout <<"the second line" <
int main ()

thr = thread (func);
thr.giuntura();
restituzione 0;

L'output è:

la prima riga
la seconda riga

Prima della funzione, Func () è definito nel programma; C'è la dichiarazione,

Discussione Thr;

che istanzia il filo, thr. A questo punto, THR non ha una funzione corrispondente. Nella funzione principale (), la prima affermazione è:

thr = thread (func);

Il lato destro di questa istruzione crea un thread senza un nome e assegna il thread alla variabile thread, thr. In questo modo, THR acquisisce una funzione. L'istruzione successiva si unisce al thread chiamato.

Distacco all'interno del thread chiamato

Un modo migliore per staccare un thread è farlo all'interno del corpo del thread chiamato. In questo caso, l'oggetto thread dovrebbe essere creato nell'ambito globale, come illustrato sopra. Quindi l'istruzione di stacca sarà nel corpo del thread chiamato, dove dovrebbe avvenire il distacco. Il seguente programma illustra questo:

#includere
#includere
Utilizzo dello spazio dei nomi std;
Discussione Thr;
void func ()
cout <<"the first line" <thr.detach ();
cout <<"the second line" <
int main ()

thr = thread (func);
thr.giuntura();
cout <<"main() function line" <restituzione 0;

L'output è:

la prima riga
la seconda riga
linea di funzione principale ()

Nessun messaggio di errore è stato emesso in fase di esecuzione. L'istruzione join () prevedeva che il thread fosse eseguito prima che il corpo della funzione principale () potesse continuare. Ciò è accaduto nonostante il fatto che il thread chiamato sia stato staccato nel mezzo della sua esecuzione, con l'affermazione,

thr.detach ();

E così la funzione principale () (thread principale) è continuata dopo il completamento del thread chiamato, con tutte le sue risorse rilasciate dall'implementazione. Nella seconda metà del thread chiamato, il thread chiamato era già staccato, anche se il thread chiamante stava ancora aspettando.

Il programma inizia con l'inclusione della libreria iostream per l'oggetto Cout. Successivamente, c'è l'inclusione della libreria di thread, che è un must. Quindi c'è l'istanziazione del thread, Thr, senza una funzione. La funzione che utilizzerà è definita subito dopo. Questa funzione ha l'affermazione distaccata dell'oggetto, thr nel suo corpo.

Nel corpo della funzione principale (), la prima istruzione crea un thread di una funzione ma senza un nome. Questo thread viene quindi assegnato a Thr. Quindi, ora ha una funzione, con il vantaggio che è stato creato nell'ambito globale, in modo che possa essere visto in Func ().

L'istruzione successiva si unisce al corpo funzione della funzione principale () al thread chiamato. Il thread è stato chiamato nella prima dichiarazione della funzione principale (). A questo punto, il corpo della funzione principale () attende che il thread chiamato corre alla sua fine e tutte le sue risorse rilasciate, sebbene fosse staccata al centro. La funzione join () fa il proprio dovere fintanto che qualsiasi cosa all'interno del thread chiamato è legittimo.

E così l'esecuzione continua con la funzione principale dopo che il thread chiamato è uscito con successo, come previsto (con tutte le sue risorse rilasciate). È per questo,

"Main () Linea di funzione"

viene emesso dopo tutte le uscite del thread chiamato.

Conclusione

Il distacco di un thread significa che il thread chiamato può continuare a eseguire, mentre il thread lo chiamato può anche continuare a eseguire. Cioè, il thread chiamante non continua più ad aspettare (blocco), dopo aver aderito. Ciò può aumentare la velocità di entrambi i fili, consentendo loro di funzionare in parallelo e aumentando così la velocità dell'intero programma. In questo caso, è meglio staccare il filo nel suo corpo, dove la comunicazione tra loro non si verificherà più. Inoltre, per raggiungere questo obiettivo, lascia che la variabile del thread venga creata nell'ambito globale senza la sua funzione. Nella funzione principale () del programma C ++, un thread anonimo, con la funzione di interesse, può essere creato e assegnato alla variabile del thread. Questo passaggio chiama la funzione del thread e quindi chiama il thread.

Quindi, dopo la dichiarazione di Detach, l'istruzione join () non ha più il suo normale ruolo di attesa (bloccare il thread chiamante), anche se potrebbe ancora aspettare. Non è consigliabile staccare il thread chiamato dal thread chiamante.