Estoy trabajando en un proyecto en el que hemos usado pthread_create para crear varios subprocesos secundarios. La lógica de creación de subprocesos no está bajo mi control, ya que está implementada por alguna otra parte del proyecto.
Cada subproceso realiza alguna operación que tarda más de 30 segundos en completarse. En condiciones normales, el programa funciona perfectamente bien. Pero el problema se produce en el momento de la terminación del programa. Necesito salir de main lo más rápido posible cuando recibo la señal SIGINT.
Cuando llamo a exit() o vuelvo desde main, se llaman los manejadores de salida y los destructores de objetos globales. Y creo que estas operaciones tienen una condición de carrera con los subprocesos en ejecución. Y creo que hay muchas condiciones de carrera, lo que dificulta resolver todas las tesis. A mi modo de ver hay dos soluciones.
Creo que la primera opción funcionará, pero no quiero terminar abruptamente el proceso. Entonces, quiero saber si es posible terminar todos los subprocesos secundarios lo más rápido posible para que el controlador de salida y el destructor puedan realizar la tarea de limpieza requerida y terminar el programa.
Revisé esta publicación, avíseme si conoce otras formas: llamada a la API POSIX para enumerar todos los pthreads que se ejecutan en un proceso
Además, hágamelo saber si hay alguna otra solución a este problema
¿Qué es lo que debe hacer antes de que el programa se cierre? Si la respuesta es 'desasignar recursos', entonces no necesita preocuparse. Si llama a _exit , el programa se cerrará inmediatamente y el sistema operativo limpiará todo por usted.
Tenga en cuenta también que lo que puede hacer con seguridad en un manipulador de señales es extremadamente limitado, por lo que no se recomienda intentar realizar ninguna limpieza usted mismo. Si estás interesado, hay una lista de lo que puedes hacer aquí . Pero no puede vaciar un archivo en el disco, por ejemplo (que es lo único que se me ocurre que podría querer hacer legítimamente aquí). Eso está fuera de los límites.
Necesito salir de main lo más rápido posible cuando recibo la señal SIGINT.
¿Cómo se define eso? Porque no hay forma de "salir lo más rápido posible" cuando recibes una señal como esa.
Puede configurar banderas, publicar en semáforos o similar para establecer un estado que indique a otros subprocesos que es hora de cerrar, o puede eliminar todo el proceso.
Si elige establecer banderas o similar para decirles a los otros subprocesos que se apaguen, establezca esas banderas y regrese desde su controlador de señal y espere que los subprocesos se comporten y el proceso se cierre limpiamente.
Si elige eliminar subprocesos, efectivamente no hay diferencia entre eliminar un subproceso, eliminar el proceso o llamar a _exit() . También podría mantenerlo simple y llamar a _exit() .
Eso es todo lo que puede elegir cuando tiene que tomar su decisión en una sola llamada de controlador de señal. Elegir uno.
Una mejor solución es utilizar señales en aumento. Por ejemplo, cuando obtiene SIGQUIT o SIGINT , establece banderas o le dice a los subprocesos que es hora de limpiar y salir del proceso, o de lo contrario . Luego, digamos cinco segundos después, lo que sea que esté cerrando su proceso envía SIGTERM y sucede el "o si no". Cuando obtiene SIGTERM , su controlador de señales simplemente llama a _exit() : esos subprocesos tuvieron su oportunidad y lo estropearon y esa es su culpa . O puede llamar a abort() para generar un archivo central y tal vez proporcionar suficiente evidencia para arreglar los hilos maliciosos que no se cierran.
Y finalmente, cinco segundos más tarde, el proceso de gestión destruirá el proceso desde la órbita con SIGKILL solo para estar seguro.