Classe de thread em Delphi
Raptor[Estúdio Mental]
http://mental.mentsu.com
(um)
Existe uma classe de thread TThread no Delphi que é usada para implementar a programação multi-thread. A maioria dos livros do Delphi menciona isso, mas basicamente eles fornecem uma breve introdução a vários membros da classe TThread e, em seguida, explicam a implementação e o uso da função Execute. de Sincronização estão concluídos. No entanto, isso não é tudo sobre programação multithread. O objetivo de escrever este artigo é complementar isso.
Um thread é essencialmente um trecho de código executado simultaneamente em um processo. Um processo possui pelo menos um thread, o chamado thread principal. Também pode haver vários subthreads ao mesmo tempo. Quando mais de um thread é usado em um processo, isso é chamado de "multithreading".
Então, como esse chamado “pedaço de código” é definido? Na verdade, é uma função ou processo (para Delphi).
Se você usar a API do Windows para criar um thread, ele será implementado por meio de uma função de API chamada CreateThread, que é definida como:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Como seus nomes dizem, os parâmetros são: atributos de thread (usados para definir atributos de segurança de thread no NT, inválidos em 9X), tamanho da pilha, endereço inicial, parâmetros, sinalizador de criação (usado para definir o estado do thread quando criado), ID do thread, e finalmente retorna o thread Handle. O endereço inicial é a entrada para a função do thread. Até que a função do thread termine, o thread termina.
O processo de execução de todo o thread é o seguinte:
Como CreateThread tem muitos parâmetros e é uma API do Windows, uma função geral de thread é fornecida na C Runtime Library (teoricamente pode ser usada em qualquer sistema operacional que suporte threads):
não assinado longo _beginthread(void (_USERENTRY *__start)(void *), não assinado __stksize, void *__arg);
Delphi também fornece uma função semelhante com a mesma funcionalidade:
função BeginThread (SecurityAttributes: Ponteiro; StackSize: LongWord; ThreadFunc: TThreadFunc; Parâmetro: Ponteiro; CreationFlags: LongWord; var ThreadId: LongWord): Integer;
As funções dessas três funções são basicamente as mesmas. Todas colocam o código da função thread em um thread independente para execução. A maior diferença entre funções de thread e funções gerais é que assim que a função de thread é iniciada, essas três funções de inicialização de thread retornam. O thread principal continua a ser executado para baixo, enquanto a função de thread é executada em um thread independente. leva para executar? Quando retorna, o thread principal não se importa e não sabe.
Em circunstâncias normais, após o retorno da função do thread, o thread é encerrado. Mas existem outras maneiras:
API do Windows:
VOID ExitThread(DWORD dwExitCode);
Biblioteca de tempo de execução C:
vazio _endthread(void);
Biblioteca de tempo de execução Delphi:
Procedimento EndThread(ExitCode: Inteiro);
Para registrar alguns dados necessários do thread (status/propriedades, etc.), o SO criará um Objeto interno para o thread. Por exemplo, no Windows, o Handle é o Handle deste Objeto interno, portanto este Objeto deve ser liberado. quando o fio termina.
Embora a programação multithread possa ser facilmente executada usando API ou RTL (Runtime Library), um processamento mais detalhado ainda é necessário. Por esse motivo, o Delphi fez um melhor encapsulamento de threads na unidade Classes. Esta é a classe de thread VCL: TThread.
Usar esta classe também é muito simples. A maioria dos livros de Delphi diz que o uso básico é: primeiro derivar sua própria classe de thread de TThread (porque TThread é uma classe abstrata e não pode gerar instâncias) e então usar o método abstrato Override: Execute( This). é a função do thread, que é a parte do código executada no thread). Se você precisar usar o objeto visual VCL, precisará fazê-lo por meio do processo Synchronize. Para detalhes específicos, não entraremos em detalhes aqui. Consulte os livros relevantes.
A próxima coisa que este artigo discutirá é como a classe TThread encapsula threads, ou seja, um estudo aprofundado da implementação da classe TThread. Porque somente compreendendo-o verdadeiramente poderemos utilizá-lo melhor.
A seguir está a declaração da classe TThread no DELPHI7 (este artigo discute apenas a implementação na plataforma Windows, portanto todo o código relacionado à plataforma Linux foi removido):
TThread = classe
privado
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: Booleano;
FTerminado: Booleano;
FSuspenso: Booleano;
FFreeOnTerminate: Booleano;
Finalizado: Booleano;
FReturnValue: Inteiro;
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
procedimento CallOnTerminate;
procedimento de classe Synchronize (ASyncRec: sobrecarga de PSynchronizeRecord);
função GetPriority: TThreadPriority;
procedimento SetPriority(Valor: TThreadPriority);
procedimento SetSuspended(Valor: Boolean);
protegido
procedimento CheckThreadError (ErrCode: sobrecarga de número inteiro);
procedimento CheckThreadError(Sucesso: sobrecarga booleana);
procedimento DoTerminate virtual;
procedimento Executar virtual;
procedimento Sincronizar (Método: sobrecarga TThreadMethod);
propriedade ReturnValue: leitura inteira FReturnValue gravação FReturnValue;
propriedade Terminada: leitura booleana FTerminada;
público
construtor Create(CreateSuspended: Boolean);
substituição do destruidor;
substituição do procedimento AfterConstruction;
currículo do procedimento;
procedimentoSuspender;
procedimento Encerrar;
função WaitFor: LongWord;
procedimento de classe Sincronizar (AThread: TThread; AMethod: sobrecarga TThreadMethod);
procedimento de classe StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
propriedade FatalException: TObject lido FFatalException;
propriedade FreeOnTerminate: leitura booleana FFreeOnTerminate gravação FFreeOnTerminate;
identificador de propriedade: THandle lê FHandle;
propriedade Prioridade: TThreadPriority lê GetPriority escreve SetPriority;
propriedade Suspended: Boolean read FSuspended write SetSuspended;
propriedade ThreadID: THandle leitura FThreadID;
propriedade OnTerminate: TNotifyEvent lê FOnTerminate escreve FOnTerminate;
fim;
A classe TThread é uma classe relativamente simples no RTL do Delphi. Não há muitos membros da classe e os atributos da classe são muito simples e claros. Este artigo conduzirá apenas uma análise detalhada de alguns métodos mais importantes dos membros da classe e do único evento: OnTerminate. .
(continua)