Classe de thread dans Delphi
Raptor[Studio Mental]
http://mental.mentsu.com
(un)
Il existe une classe de thread TThread dans Delphi qui est utilisée pour implémenter la programmation multithread. La plupart des livres Delphi le mentionnent, mais ils donnent essentiellement une brève introduction à plusieurs membres de la classe TThread, puis expliquent la fonction Execute, l'implémentation et l'utilisation. de Synchronisation sont terminés. Cependant, il ne s’agit pas uniquement de programmation multithread. Le but de la rédaction de cet article est de compléter cela.
Un thread est essentiellement un morceau de code exécuté simultanément dans un processus. Un processus possède au moins un thread, appelé thread principal. Il peut également y avoir plusieurs sous-threads en même temps. Lorsque plusieurs threads sont utilisés dans un processus, cela est appelé « multithreading ».
Alors, comment ce soi-disant « morceau de code » est-il défini ? En fait, c'est une fonction ou un processus (pour Delphi).
Si vous utilisez l'API Windows pour créer un thread, celui-ci est implémenté via une fonction API appelée CreateThread, qui est définie comme :
POIGNÉE CréerThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParamètre,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Les paramètres sont, comme leur nom l'indique : les attributs du thread (utilisés pour définir les attributs de sécurité du thread sous NT, invalides sous 9X), la taille de la pile, l'adresse de départ, les paramètres, l'indicateur de création (utilisé pour définir l'état du thread lors de sa création), l'ID du thread et renvoie enfin le fil Handle. L'adresse de départ est l'entrée de la fonction thread. Jusqu'à la fin de la fonction thread, le thread se termine.
Le processus d'exécution de l'ensemble du thread est le suivant :
Étant donné que CreateThread possède de nombreux paramètres et qu'il s'agit d'une API Windows, une fonction de thread générale est fournie dans la bibliothèque d'exécution C (en théorie, elle peut être utilisée dans n'importe quel système d'exploitation prenant en charge les threads) :
unsigned long _beginthread(void (_USERENTRY *__start)(void *), non signé __stksize, void *__arg);
Delphi fournit également une fonction similaire avec les mêmes fonctionnalités :
function BeginThread (SecurityAttributes : Pointeur ; StackSize : LongWord ; ThreadFunc : TThreadFunc ; Paramètre : Pointeur ; CreationFlags : LongWord ; var ThreadId : LongWord) : Entier ;
Les fonctions de ces trois fonctions sont fondamentalement les mêmes. Elles placent toutes le code de la fonction thread dans un thread indépendant pour exécution. La plus grande différence entre les fonctions de thread et les fonctions générales est que dès que la fonction de thread est démarrée, les trois fonctions de démarrage du thread reviennent. Le thread principal continue de s'exécuter vers le bas, tandis que la fonction de thread est exécutée dans un thread indépendant. prendre pour exécuter ? Quand il revient, le thread principal s'en fiche et ne le sait pas.
Dans des circonstances normales, après le retour de la fonction thread, le thread est terminé. Mais il existe d'autres moyens :
API Windows :
VOID ExitThread(DWORD dwExitCode);
Bibliothèque d'exécution C :
void _endthread(void);
Bibliothèque d'exécution Delphi :
PRocédure EndThread (ExitCode : Integer );
Afin d'enregistrer certaines données de thread nécessaires (statut/propriétés, etc.), le système d'exploitation créera un objet interne pour le thread. Par exemple, sous Windows, le handle est le handle de cet objet interne, cet objet doit donc être libéré. quand le fil se termine.
Bien que la programmation multithread puisse être facilement réalisée à l'aide de l'API ou de RTL (Runtime Library), un traitement plus détaillé est toujours nécessaire. Pour cette raison, Delphi a amélioré l'encapsulation des threads dans l'unité Classes. Il s'agit de la classe de thread VCL : TThread.
L'utilisation de cette classe est également très simple. La plupart des livres Delphi indiquent que l'utilisation de base est la suivante : dérivez d'abord votre propre classe de thread à partir de TThread (car TThread est une classe abstraite et ne peut pas générer d'instances), puis utilisez la méthode abstraite Override : Execute( This est la fonction de thread, qui est la partie du code exécutée dans le thread). Si vous devez utiliser l'objet visuel VCL, vous devez le faire via le processus de synchronisation. Pour des détails spécifiques, nous n’entrerons pas dans les détails ici. Veuillez vous référer aux livres pertinents.
La prochaine chose que cet article abordera est la façon dont la classe TThread encapsule les threads, c'est-à-dire une étude approfondie de l'implémentation de la classe TThread. Parce que ce n’est qu’en le comprenant vraiment que nous pourrons mieux l’utiliser.
Voici la déclaration de la classe TThread dans DELPHI7 (cet article ne traite que de l'implémentation sous la plateforme Windows, donc tout le code lié à la plateforme Linux a été supprimé) :
TThread = classe
privé
FPoignée : TPoignée ;
FThreadID : THandle ;
FCreateSuspended : booléen ;
FTerminé : booléen ;
FSuspendu : booléen ;
FFreeOnTerminate : booléen ;
FTerminé : booléen ;
FReturnValue : entier ;
FOnTerminate : TNotifyEvent ;
FSynchronize : TSynchronizeRecord ;
FFatalException : TObject ;
procédure CallOnTerminate ;
procédure de classe Synchronize (ASyncRec : PSynchronizeRecord) ;
fonction GetPriority : TThreadPriority ;
procédure SetPriority(Valeur : TThreadPriority);
procédure SetSuspended (Valeur : Booléenne);
protégé
procédure CheckThreadError (ErrCode : Integer) ;
procédure CheckThreadError (Succès : surcharge booléenne );
procédure DoTerminate ; virtuel ;
procédure Exécuter ; virtuel ; résumé ;
procédure Synchronize(Méthode : TThreadMethod); surcharge ;
propriété ReturnValue : entier lu FReturnValue écrit FReturnValue ;
propriété Terminée : lecture booléenne FTerminée ;
publique
constructeur Create(CreateSuspended: Boolean);
destructeur Détruire ;
procédure AfterConstruction ;
procédure CV ;
procédureSuspend;
procédure Terminer ;
fonction WaitFor : LongWord ;
procédure de classe Synchronize(AThread : TThread ; AMethod : TThreadMethod);
procédure de classe StaticSynchronize(AThread : TThread ; AMethod : TThreadMethod);
propriété FatalException : TObject lit FFatalException ;
propriété FreeOnTerminate : booléen lecture FFreeOnTerminate écriture FFreeOnTerminate ;
propriété Handle : THandle read FHandle ;
property Priority : TThreadPriority lecture GetPriority écriture SetPriority ;
propriété Suspended : lecture booléenne FSuspended écriture SetSuspended ;
propriété ThreadID : THandle lit FThreadID ;
propriété OnTerminate : TNotifyEvent lecture FOnTerminate écriture FOnTerminate ;
fin;
La classe TThread est une classe relativement simple dans le RTL de Delphi. Il n'y a pas beaucoup de membres de classe et les attributs de classe sont très simples et clairs. Cet article procédera uniquement à une analyse détaillée de quelques méthodes membres de classe plus importantes et du seul événement : OnTerminate. .
(à suivre)