Classe de thread em Delphi
Raptor[Estúdio Mental]
http://mental.mentsu.com
terceiro
Depois de falar sobre o construtor, vamos dar uma olhada no destruidor:
destruidor TThread.Destroy;
começar
if (FThreadID <> 0) e não FFinished então
começar
Rescindir;
se FCreateSuspended então
Retomar;
Espere;
fim;
se FHandle <> 0 então CloseHandle(FHandle);
Destruição herdada;
FFatalException.Free;
RemoverThread;
fim;
Antes de o objeto thread ser liberado, primeiro verifique se o thread ainda está em execução. Se o thread ainda estiver em execução (o ID do thread não for 0 e o sinalizador de final do thread não estiver definido), o processo Terminate será chamado para encerrar o thread. O processo Terminate simplesmente define o sinalizador Terminated da classe de thread, como no código a seguir:
Procedimento TThread.Terminate;
começar
FTerminado := Verdadeiro;
fim;
Portanto, o thread ainda deve continuar a ser executado até terminar normalmente, em vez de encerrá-lo imediatamente.
Uma pequena digressão aqui: Muitas pessoas me perguntaram como encerrar um thread "imediatamente" (é claro, referindo-se aos threads criados com TThread). Claro que não funciona! A única maneira de encerrar um thread é permitir que o método Execute conclua a execução; portanto, de modo geral, se você deseja que seu thread termine o mais rápido possível, você deve verificar constantemente o sinalizador Terminated no método Execute dentro de um curto período de tempo para que você pode sair a tempo. Este é um princípio muito importante ao projetar código encadeado!
Obviamente, se você precisar sair do thread "imediatamente", a classe TThread não será uma boa escolha, porque se você usar a API para encerrar o thread à força, o objeto do thread TThread eventualmente não será liberado corretamente e A violação de acesso ocorrerá quando o objeto for destruído. Neste caso você só pode usar funções API ou RTL para criar threads.
Se o thread estiver em um estado de inicialização suspensa, transfira o thread para o estado de execução e chame WaitFor para aguardar. Sua função é esperar até que o thread termine antes de continuar a execução. A implementação do WaitFor será explicada posteriormente.
Depois que o thread terminar, feche o identificador do thread (o identificador existe na criação normal do thread) e libere o objeto do thread criado pelo sistema operacional.
Em seguida, chame TObject.Destroy para liberar este objeto e liberar o objeto de exceção capturado e, finalmente, chame RemoveThread para reduzir o número de threads no processo.
Outros aspectos relativos às configurações de suspensão/retomada e prioridade de thread não são o foco deste artigo e não serão discutidos novamente. O que será discutido a seguir são os outros dois focos deste artigo: Synchronize e WaitFor.
Mas antes de introduzir essas duas funções, duas outras tecnologias de sincronização de threads precisam ser introduzidas: eventos e seções críticas.
Os eventos são diferentes dos eventos no Delphi. Em essência, Event é equivalente a uma variável booleana global. Possui duas operações de atribuição: Set e Reset, que equivalem a configurá-lo como True ou False. E a verificação do seu valor é feita através da operação WaitFor. Correspondendo à plataforma Windows, existem três funções API: SetEvent, ResetEvent e WaitForSingleObject (existem várias APIs que implementam a função WaitFor, esta é a mais simples).
Esses três são primitivos, portanto Event pode implementar aplicativos em multithreads que variáveis booleanas gerais não podem. As funções de Set e Reset foram mencionadas antes. Agora vamos falar sobre a função de WaitFor:
A função do WaitFor é verificar se o estado do Evento é o estado Set (equivalente a True). Caso contrário, ele retorna imediatamente. thread que chama WaitFor está em estado suspenso. Além disso, WaitFor possui um parâmetro para configuração de timeout. Se este parâmetro for 0, ele não espera e retorna o status do Evento imediatamente. Se for INFINITO, espera infinitamente até que o status Set ocorra. aguarda o número correspondente de milissegundos. Em seguida, retorna o status do Evento.
Quando o Evento transita do estado Reset para o estado Set, ele ativa outros threads suspensos devido ao evento WaitFor. É por isso que é chamado de Evento. O chamado “evento” refere-se à “transição de estado”. Essas informações de “transição de estado” podem ser passadas entre threads por meio de Eventos.
É claro que uma função semelhante também pode ser alcançada usando uma variável booleana protegida (veja a seção crítica da introdução abaixo), desde que WaitFor seja substituído por um loop de código que verifica o valor booleano. Funcionalmente não há nenhum problema, mas no uso real você descobrirá que tal espera ocupará muitos recursos da CPU, reduzirá o desempenho do sistema e afetará a velocidade de execução de outros threads, por isso é antieconômico e às vezes até possível. problemas. Portanto, não é recomendado usá-lo desta forma.
(continua)