c - pthread_join - pthread_t
Para pthread, Cómo matar un hilo secundario del hilo principal (4)
Uso pthread_create para crear varios subprocesos secundarios. A la vez, el hilo principal quiere matar todos los hilos secundarios o fallará el segmento. ¿Qué función debo usar para terminar eso? Busqué la respuesta de Google y obtuve una función como pthread_kill. Pero no sabía qué señal debería enviar al hilo hijo para matarlos. Mi entorno de ejecución es RHEL 5.4 y el lenguaje de programación es C.
Debes enviar SIG_TERM a cada uno de tus hilos, usando
int pthread_kill(pthread_t thread, int sig);
Una forma rápida de deshacerse de todos los hilos (además de los principales) es bifurcar () y seguir con el niño.
No muy limpio ...
if (fork()) exit(0); // deals also with -1...
En general, realmente no quieres matar violentamente un hilo secundario, sino que quieres pedirle que termine. De esa manera, puede estar seguro de que el niño está dejando de fumar en un lugar seguro y de que se limpian todos sus recursos.
Por lo general, hago esto con una pequeña parte del estado compartido entre padres e hijos para permitir que los padres comuniquen una "solicitud de salida" a cada niño. Esto solo puede ser un valor booleano para cada niño, protegido por un mutex. El niño comprueba este valor periódicamente (cada iteración de bucle o cualquier punto de control conveniente que tenga en su hilo hijo). Al ver que "quit_request" es verdadero, el subproceso secundario se limpia y llama a pthread_exit
.
En el lado primario, la rutina "kill_child" se ve algo así:
acquire shared mutex
set quit_request to true
pthread_join the child
La pthread_join puede tomar algún tiempo, dependiendo de la frecuencia con la que el niño verifique su solicitud de salida. Asegúrese de que su diseño pueda manejar lo que sea la demora.
Es posible "cancelar" un hilo usando pthread_cancel
. Sin embargo, esto no suele ser la mejor práctica, aunque en circunstancias extremas como un SEGFAULT puede ser un enfoque razonable.
Puede utilizar una variable global para todo el programa.
int _fCloseThreads;
Establézcalo en 1 cuando desee que los subprocesos salgan de la ejecución. Haga que los subprocesos comprueben esa variable en su "bucle" y se detengan bien cuando se establece en 1. No es necesario protegerla con un mutex.
Necesitas esperar a que se salgan los hilos. Puede utilizar unirse. Otra forma es incrementar un contador cuando un subproceso entra en su proceso de subproceso y, a continuación, degradar el contador cuando sale. El contador tendría que ser un tipo global. Use gcc atomic ops en el contador. El hilo principal, después de configurar fCloseThreads, puede esperar en el contador para ir a cero haciendo un bucle, durmiendo y verificando el conteo.
Por último, puede comprobar pthread_cleanup_push y pop. Son un modelo para permitir que un hilo se cancele en cualquier parte de su código (usa un salto largo) y luego invoca una función de limpieza final antes de salir de threadproc. Básicamente, usted pone cleanup_push en la parte superior de su threadproc y cleanup_pop en la parte inferior, crea una función de desenrollar, y luego, en ciertos puntos de cancelación, un subproceso cancelado por una llamada a pthread_cancel () regresará a threadproc y llamará a la función de desenrollar.