Explicación de hilos de demonio


237

En la documentación de Python dice:

Un hilo se puede marcar como un "hilo de demonio". La importancia de este indicador es que todo el programa Python se cierra cuando solo quedan hilos de daemon. El valor inicial se hereda del hilo de creación.

¿Alguien tiene una explicación más clara de lo que eso significa o un ejemplo práctico que muestra dónde establecería los hilos daemonic?

Aclárelo para mí: entonces, ¿la única situación en la que no establecería subprocesos daemonices cuando desea que continúen ejecutándose después de que se cierre el subproceso principal?

Respuestas:


448

Algunos subprocesos realizan tareas en segundo plano, como el envío de paquetes keepalive, o la recolección periódica de basura, o lo que sea. Estos solo son útiles cuando el programa principal se está ejecutando, y está bien matarlos una vez que los otros hilos, que no son demonios, hayan salido.

Sin hilos de daemon, tendrías que hacer un seguimiento de ellos y decirles que salgan, antes de que tu programa se pueda cerrar por completo. Al configurarlos como hilos de demonio, puede dejarlos correr y olvidarse de ellos, y cuando su programa se cierra, cualquier hilo de demonio se elimina automáticamente.


1
Entonces, si tengo un subproceso secundario que está realizando una operación de escritura de archivos que está configurada en no demonio, ¿eso significa que tengo que hacer que salga explícitamente?
Ciasto piekarz

8
@san ¿Qué hace tu hilo de escritor cuando termina de escribir? ¿Solo regresa? Si es así, eso es suficiente. Los hilos de demonio son generalmente para cosas que se ejecutan en un bucle y no salen por sí solas.
Chris Jester-Young

No hace nada, ni regresa, su único propósito es realizar la operación de escritura de archivos
Ciasto piekarz

2
@san Si se cae de la parte inferior de la función de subproceso, regresa implícitamente.
Chris Jester-Young

Regresa Noneen ese caso, pero no importa, el valor de retorno no se usa.
Chris Jester-Young

30

Digamos que estás haciendo algún tipo de widget de tablero. Como parte de esto, desea que muestre el recuento de mensajes no leídos en su casilla de correo electrónico. Entonces haces un pequeño hilo que:

  1. Conéctese al servidor de correo y pregunte cuántos mensajes no leídos tiene.
  2. Señale la GUI con el recuento actualizado.
  3. Duerme un rato.

Cuando se inicia su widget, crearía este hilo, lo designaría como un demonio y lo iniciaría. Debido a que es un demonio, no tienes que pensarlo; cuando su widget salga, el hilo se detendrá automáticamente.


18

Otros carteles dieron algunos ejemplos de situaciones en las que usaría hilos de daemon. Mi recomendación, sin embargo, es nunca usarlos.

No es porque no sean útiles, sino porque hay algunos efectos secundarios negativos que puede experimentar si los usa. Los subprocesos de Daemon aún pueden ejecutarse después de que el tiempo de ejecución de Python comience a derribar cosas en el subproceso principal, lo que causa algunas excepciones bastante extrañas.

Más información aquí:

https://joeshaw.org/python-daemon-threads-considered-harmful/

https://mail.python.org/pipermail/python-list/2005-February/343697.html

Estrictamente hablando, nunca los necesita, solo facilita la implementación en algunos casos.


¿Todavía este problema con Python 3? No hay información clara sobre estas "extrañas excepciones" en la documentación.
kheraud

55
De la publicación del blog de Joe: "Actualización de junio de 2015: este es el error de Python 1856. Se corrigió en Python 3.2.1 y 3.3, pero la solución nunca se hizo retroceder a 2.x. (Un intento de retroceder a la rama 2.7 causó otro error y fue abandonado.) Los hilos de Daemon pueden estar bien en Python> = 3.2.1, pero definitivamente no están en versiones anteriores ".
clacke

Me gustaría compartir aquí mi experiencia: tuve una función generada como Thread varias veces. Dentro de él, tuve una instancia de Python loggingy esperaba que, después de terminar el hilo, todos los objetos (descriptores de archivo para cada hilo / función), serían destruidos. Al final de mi programa, vi muchos resultados como IOError: [Errno 24] Too many open files:. Con lsof -p pid_of_program, descubrí que los FD estaban abiertos, incluso los Thread / Functions han terminado su trabajo. ¿Solución alterna? Eliminando el controlador de registro al final de la función. Así daemonicHilos, son poco fiables ...
ivanleoncz

17

Una forma más sencilla de pensarlo, tal vez: cuando regrese main, su proceso no se cerrará si todavía hay subprocesos no daemon en ejecución.

Un pequeño consejo: el apagado limpio es fácil de equivocarse cuando hay hilos y sincronización involucrados; si puede evitarlo, hágalo. Use hilos de demonio siempre que sea posible.


13

Chris ya explicó qué son los hilos de daemon, así que hablemos sobre el uso práctico. Muchas implementaciones de grupos de subprocesos usan subprocesos de daemon para trabajadores de tareas. Los trabajadores son hilos que ejecutan tareas desde la cola de tareas.

El trabajador debe seguir esperando las tareas en la cola de tareas de forma indefinida, ya que no saben cuándo aparecerá una nueva tarea. El subproceso que asigna tareas (por ejemplo, el subproceso principal) solo sabe cuándo finalizan las tareas. El subproceso principal espera en la cola de tareas para quedar vacío y luego sale. Si los trabajadores son hilos de usuario, es decir, no demonios, el programa no terminará. Seguirá esperando a estos trabajadores que se ejecutan indefinidamente, a pesar de que los trabajadores no están haciendo nada útil. Marque los hilos de demonio de los trabajadores, y el hilo principal se encargará de matarlos tan pronto como termine de manejar las tareas.


44
¡Ten cuidado con eso! Si un programa envía una tarea importante (por ejemplo, actualizar algún archivo "en segundo plano") a una cola de tareas de daemon, entonces existe el riesgo de que el programa pueda terminar antes de realizar la tarea, o peor aún, en medio de la actualización de ese archivo.
Solomon Slow

10

Citando a Chris: "... cuando su programa se cierra, todos los hilos de demonio se eliminan automáticamente". Creo que eso lo resume todo. Debe tener cuidado cuando los use, ya que terminan abruptamente cuando el programa principal se ejecuta hasta su finalización.


4

Cuando su segundo subproceso no es Daemon, el subproceso principal principal de su aplicación no puede salir porque sus criterios de salida también están vinculados a la salida de subprocesos que no son Daemon. Los hilos no se pueden matar por la fuerza en python, por lo tanto, su aplicación tendrá que esperar realmente a que salgan los hilos que no son Daemon. Si este comportamiento no es lo que desea, configure su segundo hilo como daemon para que no impida que su aplicación salga.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.