Thread-Klasse in Delphi
Raptor[Mental Studio]
http://mental.mentsu.com
(eins)
In Delphi gibt es eine Thread-Klasse TThread, die zur Implementierung der Multi-Thread-Programmierung verwendet wird. Die meisten Delphi-Bücher erwähnen dies, geben jedoch im Grunde eine kurze Einführung in mehrere Mitglieder der TThread-Klasse und erläutern anschließend die Implementierung und Verwendung der Funktion von Synchronize sind abgeschlossen. Dies ist jedoch nicht alles zur Multithread-Programmierung. Der Zweck des Schreibens dieses Artikels besteht darin, dies zu ergänzen.
Ein Thread ist im Wesentlichen ein Teil des Codes, der gleichzeitig in einem Prozess ausgeführt wird. Ein Prozess verfügt über mindestens einen Thread, den sogenannten Hauptthread. Es können auch mehrere Unterthreads gleichzeitig vorhanden sein. Wenn in einem Prozess mehr als ein Thread verwendet wird, spricht man von „Multithreading“.
Wie ist dieses sogenannte „Stück Code“ definiert? Tatsächlich handelt es sich um eine Funktion oder einen Prozess (für Delphi).
Wenn Sie die Windows-API zum Erstellen eines Threads verwenden, wird dieser über eine API-Funktion namens CreateThread implementiert, die wie folgt definiert ist:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
Die Parameter lauten wie der Name schon sagt: Thread-Attribute (wird zum Festlegen von Thread-Sicherheitsattributen unter NT verwendet, ungültig unter 9X), Stapelgröße, Startadresse, Parameter, Erstellungsflag (wird zum Festlegen des Thread-Status beim Erstellen verwendet), Thread-ID usw gibt schließlich den Thread-Handle zurück. Die Startadresse ist der Eingang zur Thread-Funktion. Bis die Thread-Funktion endet, endet der Thread.
Der Ausführungsprozess des gesamten Threads ist wie folgt:
Da CreateThread viele Parameter hat und eine Windows-API ist, wird in der C-Laufzeitbibliothek eine allgemeine Thread-Funktion bereitgestellt (theoretisch kann sie in jedem Betriebssystem verwendet werden, das Threads unterstützt):
unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg);
Delphi bietet auch eine ähnliche Funktion mit der gleichen Funktionalität:
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): Integer;
Die Funktionen dieser drei Funktionen sind grundsätzlich gleich. Sie legen den Code in der Thread-Funktion zur Ausführung in einen unabhängigen Thread. Der größte Unterschied zwischen Thread-Funktionen und allgemeinen Funktionen besteht darin, dass, sobald die Thread-Funktion gestartet wird, die drei Thread-Startfunktionen weiterhin nach unten ausgeführt werden, während die Thread-Funktion in einem unabhängigen Thread ausgeführt wird Zur Ausführung nehmen? Wenn es zurückkommt, ist es dem Hauptthread egal und er weiß es nicht.
Unter normalen Umständen wird der Thread nach der Rückkehr der Thread-Funktion beendet. Aber es gibt auch andere Möglichkeiten:
Windows-API:
VOID ExitThread(DWORD dwExitCode);
C-Laufzeitbibliothek:
void _endthread(void);
Delphi-Laufzeitbibliothek:
PROcedure EndThread(ExitCode: Integer);
Um einige notwendige Thread-Daten (Status/Eigenschaften usw.) aufzuzeichnen, erstellt das Betriebssystem ein internes Objekt für den Thread. In Windows ist das Handle beispielsweise das Handle dieses internen Objekts, daher sollte dieses Objekt freigegeben werden wenn der Thread endet.
Obwohl die Multithread-Programmierung problemlos über API oder RTL (Runtime Library) durchgeführt werden kann, ist dennoch eine detailliertere Verarbeitung erforderlich. Aus diesem Grund hat Delphi eine bessere Kapselung von Threads in der Classes-Einheit vorgenommen. Dies ist die VCL-Thread-Klasse
Die Verwendung dieser Klasse ist ebenfalls sehr einfach. In den meisten Delphi-Büchern heißt es, dass die grundlegende Verwendung darin besteht, zuerst Ihre eigene Thread-Klasse von TThread abzuleiten (da TThread eine abstrakte Klasse ist und keine Instanzen generieren kann) und dann die abstrakte Methode Override verwenden: Execute( This ist die Thread-Funktion, also der Teil des Codes, der im Thread ausgeführt wird. Wenn Sie das visuelle VCL-Objekt verwenden müssen, müssen Sie dies über den Synchronisierungsprozess tun. Auf konkrete Details gehen wir hier nicht näher ein. Bitte beziehen Sie sich auf entsprechende Bücher.
Als nächstes wird in diesem Artikel erläutert, wie die TThread-Klasse Threads kapselt, dh eine eingehende Untersuchung der Implementierung der TThread-Klasse. Denn nur wenn wir es wirklich verstehen, können wir es besser nutzen.
Das Folgende ist die Deklaration der TThread-Klasse in DELPHI7 (in diesem Artikel wird nur die Implementierung unter der Windows-Plattform erläutert, daher wurde der gesamte Code im Zusammenhang mit der Linux-Plattform entfernt):
TThread = Klasse
Privat
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: Boolean;
FTerminated: Boolean;
FSuspended: Boolean;
FFreeOnTerminate: Boolean;
FFinished: Boolean;
FReturnValue: Integer;
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
Prozedur CallOnTerminate;
Klassenprozedur Synchronize(ASyncRec: PSynchronizeRecord);
Funktion GetPriority: TThreadPriority;
procedure SetPriority(Value: TThreadPriority);
procedure SetSuspended(Value: Boolean);
geschützt
procedure CheckThreadError(ErrCode: Integer);
Prozedur CheckThreadError(Erfolg: Boolean-Überladung);
Prozedur DoTerminate; virtuell;
Prozedur Ausführen; virtuell;
procedure Synchronize(Methode: TThreadMethod);
Eigenschaft ReturnValue: Integer read FReturnValue write FReturnValue;
Eigenschaft Terminated: Boolean read FTerminated;
öffentlich
Konstruktor Create(CreateSuspended: Boolean);
Destruktor Zerstören; überschreiben;
Prozedur AfterConstruction;
Verfahren Lebenslauf;
procedureSuspend;
Prozedur beenden;
Funktion WaitFor: LongWord;
Klassenprozedur Synchronize(AThread: TThread; AMethod: TThreadMethod-Überladung);
Klassenprozedur StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
Eigenschaft FatalException: TObject read FFatalException;
Eigenschaft FreeOnTerminate: Boolean read FFreeOnTerminate write FFreeOnTerminate;
Eigenschaft Handle: THandle read FHandle;
Eigenschaftspriorität: TThreadPriority read GetPriority write SetPriority;
Eigenschaft Suspended: Boolean read FSuspended write SetSuspended;
Eigenschaft ThreadID: THandle read FThreadID;
Eigenschaft OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
Ende;
Die TThread-Klasse ist eine relativ einfache Klasse in Delphis RTL. Es gibt nicht viele Klassenmitglieder und die Klassenattribute sind sehr einfach und klar. In diesem Artikel werden nur einige weitere wichtige Klassenmitgliedsmethoden und das einzige Ereignis analysiert .
(fortgesetzt werden)