¿Por qué el subproceso de python.Thread tiene “inicio”, pero no “detener”?

El subproceso del módulo de Python tiene un Thread objeto que se utiliza para ejecutar procesos y funciones en un subproceso diferente. Este objeto tiene un método de start , pero ningún método de stop . ¿Cuál es la razón por la que no se puede detener un Thread se llama un método de stop simple? Puedo imaginar casos en los que no es conveniente utilizar el método de join

start puede ser genérico y tiene sentido porque solo dispara el objective del hilo, pero ¿qué haría una stop genérica? Dependiendo de lo que haga su hilo, podría tener que cerrar las conexiones de red, liberar recursos del sistema, descargar archivos y otras secuencias, o cualquier otra cantidad de tareas personalizadas, no triviales. Cualquier sistema que pudiera hacer incluso la mayoría de estas cosas de una manera genérica agregaría tanta sobrecarga a cada hilo que no valdría la pena, y sería tan complicado y lleno de casos especiales que sería casi imposible trabajar con. Puede realizar un seguimiento de todos los subprocesos creados sin join a ellos en su subproceso principal, luego verificar su estado de ejecución y transmitirles algún tipo de mensaje de terminación cuando el subproceso principal se apaga solo.

Definitivamente es posible implementar un método Thread.stop como se muestra en el siguiente código de ejemplo:

 import threading import sys class StopThread(StopIteration): pass threading.SystemExit = SystemExit, StopThread class Thread2(threading.Thread): def stop(self): self.__stop = True def _bootstrap(self): if threading._trace_hook is not None: raise ValueError('Cannot run thread with tracing!') self.__stop = False sys.settrace(self.__trace) super()._bootstrap() def __trace(self, frame, event, arg): if self.__stop: raise StopThread() return self.__trace class Thread3(threading.Thread): def _bootstrap(self, stop_thread=False): def stop(): nonlocal stop_thread stop_thread = True self.stop = stop def tracer(*_): if stop_thread: raise StopThread() return tracer sys.settrace(tracer) super()._bootstrap() ################################################################################ import time def main(): test = Thread2(target=printer) test.start() time.sleep(1) test.stop() test.join() def printer(): while True: print(time.time() % 1) time.sleep(0.1) if __name__ == '__main__': main() 

La clase Thread3 parece ejecutar el código aproximadamente un 33% más rápido que la clase Thread2 .

Matar hilos de una manera confiable no es muy fácil. Piense en las limpiezas requeridas: ¿qué lockings (que podrían compartirse con otros subprocesos) deberían liberarse automáticamente? De lo contrario, fácilmente se encontrará con un punto muerto!

La mejor manera es implementar un apagado adecuado , y luego configurar

 mythread.shutdown = True mythread.join() 

para detener el hilo.

Por supuesto, tu hilo debería hacer algo como

 while not this.shutdown: continueDoingSomething() releaseThreadSpecificLocksAndResources() 

para comprobar con frecuencia la bandera de apagado. Alternativamente, puede confiar en mecanismos de señalización específicos del sistema operativo para interrumpir un hilo, capturar la interrupción y luego limpiar .

La limpieza es la parte más importante!

Detener un hilo debe estar en manos del progtwigdor para implementar. Como el diseño de su hilo para verificarlo, hay solicitudes para que termine de inmediato. Si Python (o cualquier lenguaje de subprocesamiento) le permitiera simplemente detener un subproceso, entonces tendría un código que simplemente se detuvo. Esto es propenso a errores, etc.

Imagínese si su hilo como resultado de escritura en un archivo cuando lo mató / detuvo. Entonces el archivo podría estar inacabado y corrupto. Sin embargo, si simplemente señala el hilo que desea que se detenga, podría cerrar el archivo, borrarlo, etc. Usted, el progtwigdor, decidió cómo manejarlo. Python no puede adivinar por ti.

Yo sugeriría leer sobre la teoría de subprocesos múltiples. Un comienzo decente: http://en.wikipedia.org/wiki/Multithreading_(software )#Multithreading

En algunas plataformas no puedes “detener” un hilo por la fuerza. También es malo hacerlo ya que el hilo no podrá limpiar los recursos asignados. Y puede suceder cuando el hilo está haciendo algo importante, como I / O.