2009-11-06 17 views
5

Quiero implementar tareas interrumpibles basadas en hilos de fondo. ¿Cuál es la forma más limpia de implementar el método TTask.Stop? ¿Cómo puedo abortar el hilo de fondo?¿Aborta un hilo?

El código ejecutado en el contexto del subproceso se pasa a la tarea utilizando un método anónimo y puede contener llamadas de bloqueo, por lo que no puedo confiar en que el indicador Terminated se verifique regularmente desde el código.

Gracias por cualquier entrada.

Usando D2010 en caso de que importa (algunas cosas en TThread parecen haber cambiado)

Respuesta

7

No hay manera de abortar con seguridad un hilo conductor. Esto es cierto para los programas de Windows escritos en Delphi o no, y si se usa Delphi 2010 o anterior. Es una limitación del sistema operativo si desea llamarlo así, pero en realidad es una limitación de subprocesamiento, ya que abortar un hilo sin asegurarse de que no tiene bloqueos o algo así causará estragos en su programa.

Lo que puede hacer es llamar a la función TerminateThread() API, que es evil. Lea la lista de problemas y advertencias en este enlace y vea si aún desea llamarlo. No hay otra manera de que funcione sin cooperación del código de la tarea.

7

Aísle el trabajo en un proceso separado. Dependiendo de cómo te comuniques con el trabajo de fondo, esta es probablemente la mejor manera de garantizar que puedas abortarlo limpiamente.

Por ejemplo, probablemente no sea una buena idea usar la memoria compartida para la comunicación; use archivos o tuberías, o un mecanismo similar que no se rompa ni se detenga cuando se mata al otro extremo. Si usa mutexes con nombre para la sincronización de procesos cruzados, tenga en cuenta que hay un estado de error particular para estas primitivas de sincronización: WAIT_ABANDONED es devuelto por WaitForSingleObject y sus amigos si un thread (o, implícitamente, el hilo principal del proceso) terminado sin liberarlo limpiamente. Básicamente, esto significa que debe usar un enfoque transaccional por etapas para la transferencia de datos, de modo que pueda ignorar el estado posiblemente inconsistente que se estaba modificando en el momento de la terminación.

+0

Esa es una buena (+1) respuesta; cf. Enlazado de Python, donde mucho se hace de Global Interpreter Lock, que es responsable tanto de la seguridad del hilo (bueno) como de todos los propósitos prácticos, limita el código multiproceso a un solo núcleo (malo). La mejor solución para ese problema es no utilizar hilos, sino procesos a través del paquete de multiprocesamiento, y lo que se gana con esta capacidad instantánea de escalar a través de múltiples máquinas, lo que eventualmente se vuelve necesario para grandes escalas de todos modos. En lugar de preocuparse por la seguridad de los hilos, sería mejor tener una administración de multiprocesos fácil (más fácil) en Delphi. –

+0

Los semáforos no tienen un estado "abandonado" porque no tienen ninguna noción incorporada de propiedad. (En lo que respecta al sistema operativo, un hilo no puede "contener" un semáforo). Solo un mutex puede abandonarse de manera detectable. –

+0

Esta puede ser una buena manera de implementar tareas interrumpibles con código de bloqueo, sin embargo, no veo cómo la funcionalidad de la pregunta (una tarea interrumpible para métodos anónimos) debe implementarse así con Delphi. Tendría que haber un compilador en tiempo de ejecución, para crear un ejecutable (que se genere como un proceso diferente) del método anónimo, ¿no? – mghie