Clase de hilo en Delphi
Raptor[Estudio mental]
http://mental.mentsu.com
tercero
Después de hablar del constructor, veamos el destructor:
destructor TThread.Destroy;
comenzar
si (FThreadID <> 0) y no FFinished entonces
comenzar
Terminar;
si FCreateSuspended entonces
Reanudar;
Esperar;
fin;
si FHandle <> 0 entonces CloseHandle(FHandle);
heredado Destruir;
FFatalException.Gratis;
Quitar hilo;
fin;
Antes de liberar el objeto del hilo, primero verifique si el hilo aún se está ejecutando. Si el hilo aún se está ejecutando (el ID del hilo no es 0 y el indicador de fin del hilo no está configurado), se llama al proceso Terminar para finalizar el hilo. El proceso Terminar simplemente establece el indicador Terminado de la clase de subproceso, como en el siguiente código:
Procedimiento TThread.Terminate;
comenzar
FTerminado := Verdadero;
fin;
Por lo tanto, el hilo aún debe continuar ejecutándose hasta que finalice normalmente, en lugar de terminar el hilo inmediatamente.
Una pequeña digresión aquí: Mucha gente me ha preguntado cómo terminar un hilo "inmediatamente" (por supuesto, refiriéndose a los hilos creados con TThread). ¡Por supuesto que no funciona! La única forma de terminar un hilo es dejar que el método Execute complete la ejecución, por lo que, en términos generales, si desea que su hilo termine lo antes posible, debe verificar constantemente el indicador Terminado en el método Execute dentro de un corto período de tiempo para que que puedas salir a tiempo. ¡Este es un principio muy importante al diseñar código con subprocesos!
Por supuesto, si debe poder salir del hilo "inmediatamente", entonces la clase TThread no es una buena opción, porque si usa la API para terminar el hilo por la fuerza, el objeto del hilo TThread eventualmente no se liberará correctamente y La violación de acceso ocurrirá cuando el objeto sea destruido. En este caso, solo puede utilizar funciones API o RTL para crear subprocesos.
Si el subproceso está en un estado de inicio suspendido, transfiera el subproceso al estado de ejecución y luego llame a WaitFor para esperar. Su función es esperar hasta que el subproceso finalice antes de continuar con la ejecución. La implementación de WaitFor se explicará más adelante.
Una vez finalizado el subproceso, cierre el identificador del subproceso (el identificador existe durante la creación normal del subproceso) y suelte el objeto del subproceso creado por el sistema operativo.
Luego llame a TObject.Destroy para liberar este objeto y liberar el objeto de excepción capturado, y finalmente llame a RemoveThread para reducir la cantidad de subprocesos en el proceso.
Otros aspectos relacionados con Suspender/Reanudar y la configuración de prioridad de subprocesos no son el tema central de este artículo y no se discutirán nuevamente. Lo que se discutirá a continuación son los otros dos enfoques de este artículo: Sincronizar y Esperar.
Pero antes de introducir estas dos funciones, es necesario introducir otras dos tecnologías de sincronización de subprocesos: eventos y secciones críticas.
Los eventos son diferentes a los eventos en Delfos. En esencia, Event es equivalente a una variable booleana global. Tiene dos operaciones de asignación: Establecer y Restablecer, que equivalen a establecerlo en Verdadero o Falso. Y la verificación de su valor se realiza mediante la operación WaitFor. Correspondiente a la plataforma Windows, existen tres funciones API: SetEvent, ResetEvent y WaitForSingleObject (existen varias API que implementan la función WaitFor, esta es la más simple).
Estos tres son primitivos, por lo que Event puede implementar aplicaciones en subprocesos múltiples que las variables booleanas generales no pueden. Las funciones de Set y Reset se han mencionado antes. Ahora hablemos de la función de WaitFor:
La función de WaitFor es verificar si el estado del Evento es el estado Establecido (equivalente a Verdadero). Si es así, regresa inmediatamente. Si no, espera a que cambie al estado Establecido. El hilo que llama a WaitFor está en estado suspendido. Además, WaitFor tiene un parámetro para la configuración del tiempo de espera. Si este parámetro es 0, no espera y devuelve el estado del Evento inmediatamente. Si es INFINITO, espera infinitamente hasta que ocurra el estado Establecido. espera el número correspondiente de milisegundos y luego devuelve el estado del evento.
Cuando el evento pasa del estado Restablecer al estado Establecer, activa otros subprocesos suspendidos debido al evento WaitFor. Por eso se llama Evento. El llamado "evento" se refiere a una "transición de estado". Esta información de "transición de estado" se puede pasar entre subprocesos a través de Eventos.
Por supuesto, también se puede lograr una función similar utilizando una variable booleana protegida (consulte la introducción de la sección crítica a continuación), siempre que WaitFor se reemplace con un bucle de código que verifique el valor booleano. Funcionalmente no hay ningún problema, pero en el uso real encontrará que dicha espera ocupará muchos recursos de la CPU, reducirá el rendimiento del sistema y afectará la velocidad de ejecución de otros subprocesos, por lo que no es económico y, a veces, incluso es posible. problemas. Por lo que no se recomienda utilizarlo de esta manera.
(continuará)