Para que haya alguna unión, se necesitan dos hilos. Un hilo llama al otro hilo. Unirse a un hilo significa que, mientras el hilo de llamadas se está ejecutando, se detendría en una posición y esperaría que el hilo llamado complete su ejecución (hasta su final), antes de continuar su propia ejecución. En la posición donde se detiene el hilo, hay una expresión de unión. Tal detección se llama bloqueo.
Si el hilo llamado está tardando demasiado en completarse y probablemente ha hecho lo que el hilo de llamada esperaba que hiciera, entonces el hilo de llamadas puede separarlo. Después de separarse, si el hilo llamado se completa después del hilo de llamadas, no debería haber ningún problema. Separar significa romper la unión (enlace).
Recordar
Un hilo es una función de nivel superior que se ha encerrado en un objeto de subproceso, instanciado desde la clase de subproceso. Instanciar el hilo con la función de nivel superior significa llamar a la función. Aquí hay un programa de hilo simple, con la declaración de unión:
#incluir
#incluir
usando el espacio de nombres STD;
vacío func ()
cout <<"… from thread!" <<'\n';
int main ()
hilo thd (func);
thd.unirse();
/* declaraciones */
regresar 0;
Aquí hay dos hilos: el objeto, THD y la función principal (). La función principal es como el hilo principal. Tenga en cuenta la inclusión de la biblioteca de subprocesos. La salida es:
... desde el hilo!
En el símbolo del sistema, un programa C ++ 20 con subprocesos debe comandarse de la siguiente manera, para el compilador G ++:
G ++ -std = muestra de C ++ 2a.CC -LPTHREAD -O Muestra.exe
Contenido del artículo
sintaxis de separar ()
La sintaxis DETACH () es simple; es:
threadObject.despegar()
Esta función miembro del objeto de hilo regresa vacío. ThreadObject es el objeto de subproceso del hilo cuya función se está ejecutando. Cuando la función de un hilo se está ejecutando, el hilo se llama hilo de ejecución.
Un hilo solo se puede separar después de que se haya unido; De lo contrario, el hilo ya está en estado separado.
Ambigüedad de separarse en el cuerpo del hilo de llamadas
En el siguiente programa, el hilo llamado se separa en el cuerpo del hilo de llamada:
#incluir
#incluir
#incluir
usando el espacio de nombres STD;
string globl = string ("en la tierra!");
vacío func (string st)
String Fin = "Living" + St;
cout <
int main ()
hilo thr (func, globl);
thr.unirse();
thr.despegar();
regresar 0;
La salida de la computadora del autor en tiempo de ejecución fue:
Viviendo en la tierra!
Terminar llamado después de lanzar una instancia de 'std :: system_error'
What (): argumento no válido
Abortado (núcleo arrojado)
La salida adecuada esperada debe ser solo:
Viviendo en la tierra!
Cuando un hilo finaliza su ejecución, la implementación libera todos los recursos que poseía. Cuando se une un hilo, el cuerpo del hilo de llamada espera en ese punto hasta que el hilo llamado complete su ejecución, entonces el cuerpo del hilo de llamadas continúa su propia ejecución.
El problema de la presencia de la salida adicional es que, aunque el hilo llamado podría haber completado su tarea dada, sus recursos no se habían quitado, pero la función de separación () causó que el cuerpo de la función de llamadas continuara ejecutando. En ausencia de la función DETACH (), el hilo llamado se habría completado, además de todos sus recursos quitados; y la salida habría sido la simple única línea esperada.
Para convencer más al lector, considere el siguiente programa, que es el mismo que el anterior, pero con las declaraciones Join () y DETACH () comentadas:
#incluir
#incluir
#incluir
usando el espacio de nombres STD;
string globl = string ("en la tierra!");
vacío func (string st)
String Fin = "Living" + St;
cout <
int main ()
hilo thr (func, globl);
// thr.unirse();
// thr.despegar();
regresar 0;
La salida de la computadora del autor es:
Terminar llamado sin una excepción activa
Abortado (núcleo arrojado)
La función Main () corrió hasta su final sin esperar a que el hilo haga nada. Y así, el hilo no pudo mostrar su salida.
Nombre del hilo en el alcance global
Se puede instanciar un hilo en el alcance global. El siguiente programa ilustra esto:
#incluir
#incluir
usando el espacio de nombres STD;
hilo thr;
vacío func ()
cout <<"the first line" <cout <<"the second line" <
int main ()
thr = hilo (func);
thr.unirse();
regresar 0;
La salida es:
la primera línea
la segunda línea
Antes de la función, func () se define en el programa; hay la declaración,
hilo thr;
que instancia el hilo, thr. En este punto, THR no tiene una función correspondiente. En la función main (), la primera declaración es:
thr = hilo (func);
El lado derecho de esta declaración crea un hilo sin un nombre y asigna el hilo a la variable de subproceso, thr. De esta manera, THR adquiere una función. La siguiente declaración se une al hilo llamado.
Separarse dentro del hilo llamado
Una mejor manera de separar un hilo es hacerlo dentro del cuerpo del hilo llamado. En este caso, el objeto de subproceso tendría que crearse en el alcance global, como se ilustra arriba. Entonces la declaración de separación estará en el cuerpo del hilo llamado, donde se debe hacer desprendimiento. El siguiente programa ilustra esto:
#incluir
#incluir
usando el espacio de nombres STD;
hilo thr;
vacío func ()
cout <<"the first line" <thr.despegar();
cout <<"the second line" <
int main ()
thr = hilo (func);
thr.unirse();
cout <<"main() function line" <regresar 0;
La salida es:
la primera línea
la segunda línea
línea de función main ()
No se emitió ningún mensaje de error en tiempo de ejecución. La instrucción unión () esperaba que el hilo se ejecute antes de que el cuerpo de la función main () pudiera continuar. Eso sucedió a pesar del hecho de que el hilo llamado se separó en el medio de su ejecución, con la declaración,
thr.despegar();
Y así la función principal () (hilo principal) continuó después de que el hilo llamado se haya completado, con todos sus recursos publicados por la implementación. En la segunda mitad del hilo llamado, el hilo llamado ya estaba separado, aunque el hilo de llamada todavía estaba esperando.
El programa comienza con la inclusión de la biblioteca IOSTream para el objeto Cout. A continuación, está la inclusión de la biblioteca de subprocesos, que es imprescindible. Luego está la instanciación del hilo, thr, sin función. La función que usará se define justo después. Esta función tiene la declaración separada del objeto, THR dentro de su cuerpo.
En el cuerpo de la función main (), la primera declaración crea un hilo de una función pero sin un nombre. Este hilo se asigna a thr. Entonces, THR ahora tiene una función, con la ventaja de que se creó en el alcance global, para que se pueda ver en func ().
La siguiente declaración se une al cuerpo de función de la función main () a la hilo llamado. El hilo se llamó en la primera declaración de la función principal (). En este punto, el cuerpo de la función principal () espera a que el hilo llamado se ejecute hasta su fin y todos sus recursos liberados, aunque fue separado en su medio. La función unitar () tiene su deber siempre que cualquier cosa dentro del hilo llamado sea legítimo.
Y así, la ejecución continúa con la función principal después de que el hilo llamado ha salido con éxito, como se anticipó (con todos sus recursos publicados). Es por eso que,
"Línea de función principal ()"
se emite después de todas las salidas del hilo llamado.
Conclusión
Descartar un hilo significa que el hilo llamado puede continuar ejecutándose, mientras que el hilo llamado también puede continuar ejecutándose. Es decir, el hilo de llamadas ya no continúa esperando (bloquear), después de unirse. Esto puede aumentar la velocidad de ambos hilos, permitiéndoles funcionar en paralelo y, por lo tanto, aumentar la velocidad de todo el programa. En este caso, es mejor separar el hilo en su cuerpo, donde la comunicación entre ellos ya no ocurrirá. Además, para lograr esto, deje que la variable de hilo se cree en el alcance global sin su función. En la función Main () del programa C ++, se puede crear y asignarse un hilo anónimo, con la función de interés, a la variable de subproceso. Este paso llama a la función de subproceso, y así, llama al hilo.
Entonces, después de la declaración de separación, la declaración Join () ya no tiene su papel normal de esperar (bloquear el hilo de llamadas), aunque aún podría esperar. No se recomienda separar el hilo llamado del hilo de llamadas.