2010-09-29 14 views
17

Utilizo pthread_create para crear varios subprocesos secundarios. En un momento, el hilo principal quiere matar a todos los hilos secundarios o habrá un fallo del 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.Para pthread, Cómo matar subprocesos secundarios del subproceso principal

+2

wow, matar a todos los hilos porque habrá una segfault? ¿Estás bromeando? Nunca me gustaría un código que se maneje así. –

+1

Hablando en realidad, gdb el volcado del núcleo encontrado cuando se deconstruyeron los objetos globales de salida del hilo principal. Por lo tanto, algunos subprocesos secundarios actualmente pueden usar dicha variable y el error de segmento se imprime en mi pantalla. Aunque la lógica es correcta y la falla del segmento no tendrá ningún efecto en mi programa porque está terminado. – terry

+2

Corrige la lógica. Si los otros hilos todavía están haciendo un trabajo útil, ¿por qué intentan terminar el programa? Si los otros subprocesos todavía necesitan estos objetos, incluso cuando 'main' sale del alcance, ¿por qué se asignan en la pila' main's? –

Respuesta

20

Es posible "cancelar" un hilo usando pthread_cancel. Sin embargo, esta no es la mejor práctica, sin embargo, en circunstancias extremas, como SEGFAULT, se puede considerar un enfoque razonable.

+1

Hay un ejemplo en esta url http://linux.die.net/man/3/pthread_cleanup_push – enthusiasticgeek

+4

¿Por qué 'pthread_cancel' no se considera la mejor práctica? Y si no es una buena práctica, ¿qué es? – darnir

6

usted debe enviar SIG_TERM a cada uno de sus hilos, utilizando

int pthread_kill(pthread_t thread, int sig); 

Una forma rápida de deshacerse de todos los temas (además de la principal) es tenedor() y seguir adelante con el niño.
No hiper limpia ...

if (fork()) exit(0); // deals also with -1... 
24

En general, usted realmente no quiere matar violentamente a un hilo hijo, sino que desea pedir a terminar. De esta forma, puede estar seguro de que el niño abandona su trabajo en un lugar seguro y todos sus recursos se limpian.

Generalmente hago esto con un pequeño trozo de estado compartido entre padres e hijos para permitir que los padres comuniquen una "solicitud de abandono" a cada niño. Esto solo puede ser un valor booleano para cada hijo, protegido por un mutex. El niño verifica 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 hilo secundario se limpia y llama al pthread_exit.

En el lado de los padres, la rutina "kill_child" se ve algo como esto:

acquire shared mutex 
set quit_request to true 
pthread_join the child 

El pthread_join puede llevar algún tiempo, dependiendo de la frecuencia con la que el niño comprueba su solicitud dejar de fumar. Asegúrese de que su diseño pueda manejar cualquier retraso.

+0

Si bien en general es una buena práctica adquirir un mutex antes de modificar cualquier memoria compartida entre hilos, el hecho de que este sea un solo indicador que se verifica para un estado distinto de cero (o falso) significa que realmente no necesita agarrar un mutex En este caso, realmente no hay mucho que pueda salir mal desde una perspectiva de coherencia de datos. –

+2

@Brent: [Esta pregunta] (http://stackoverflow.com/questions/21183261/is-a-race-condition-possible-when-only-one-thread-writes-to-a-bool-variable-in -c) muestra un ejemplo en el que incluso una sola bandera escrita una vez puede conducir a una condición de carrera después de las optimizaciones del compilador. – dshepherd

+0

Hermoso, esto funciona maravillosamente. – djthoms

2

Puede usar una variable global para todo el programa.

int _fCloseThreads;

Configúrelo en 1 cuando desee que los subprocesos dejen de ejecutarse. Haga que los hilos comprueben esa variable en su "bucle" y salga bien cuando se establece en 1. No es necesario protegerla con un mutex.

Debe esperar a que se cierren los subprocesos. Puedes usar join Otra forma es incrementar un contador cuando un hilo ingresa a su proceso de hilo y luego degradar el contador cuando sale. El contador necesitaría ser una especie de global. Usa gcc atomic ops en el mostrador. El hilo principal, después de establecer fCloseThreads, puede esperar en el contador para ir a cero haciendo bucles, durmiendo y verificando el conteo.

Finalmente, puede que finalice la descarga de pthread_cleanup_push y pop. Son un modelo que permite que un hilo se cancele en cualquier parte de su código (usa un salto largo) y luego llama a una función de limpieza final antes de salir de threadproc. Básicamente pone cleanup_push en la parte superior de threadproc y cleanup_pop en la parte inferior, crea una función de desenrollado, y luego en ciertos puntos de cancelación un hilo cancelado por una llamada a pthread_cancel() regresará a threadproc y llamará a la función desenrollar.

+1

http://linux.die.net/man/3/pthread_cleanup_push tiene un ejemplo. – enthusiasticgeek

Cuestiones relacionadas