Thread class in Delphi
Raptor[Mental Studio]
http://mental.mentsu.com
(one)
There is a thread class TThread in Delphi that is used to implement multi-thread programming. Most Delphi books mention this, but basically they give a brief introduction to several members of the TThread class, and then explain the Execute function. The implementation and usage of Synchronize are complete. However, this is not all of multi-threaded programming. The purpose of writing this article is to supplement this.
A thread is essentially a piece of code running concurrently in a process. A process has at least one thread, the so-called main thread. There can also be multiple sub-threads at the same time. When more than one thread is used in a process, it is called "multithreading".
So how is this so-called "piece of code" defined? In fact, it is a function or process (for Delphi).
If you use the Windows API to create a thread, it is implemented through an API function called CreateThread, which is defined as:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWord dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
The parameters are as their names say: thread attributes (used to set thread security attributes under NT, invalid under 9X), stack size, starting address, parameters, creation flag (used to set thread The state when created), thread ID, and finally returns the thread Handle. The starting address is the entrance to the thread function. Until the thread function ends, the thread ends.
The execution process of the entire thread is as follows:
Because CreateThread has many parameters and is a Windows API, a general thread function is provided in the C Runtime Library (theoretically it can be used in any OS that supports threads):
unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg);
Delphi also provides a similar function with the same functionality:
function BeginThread(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): Integer;
The functions of these three functions are basically the same. They all put the code in the thread function into an independent thread for execution. The biggest difference between thread functions and general functions is that as soon as the thread function is started, the three thread startup functions return. The main thread continues to execute downwards, while the thread function is executed in an independent thread. How long does it take to execute? When it returns, the main thread doesn't care and doesn't know.
Under normal circumstances, after the thread function returns, the thread is terminated. But there are other ways:
Windows API:
VOID ExitThread(DWORD dwExitCode);
C Runtime Library:
void _endthread(void);
Delphi Runtime Library:
PRocedure EndThread(ExitCode: Integer);
In order to record some necessary thread data (status/properties, etc.), the OS will create an internal Object for the thread. For example, in Windows, the Handle is the Handle of this internal Object, so this Object should be released when the thread ends.
Although multi-thread programming can be easily performed using API or RTL (Runtime Library), more detailed processing is still required. For this reason, Delphi has made a better encapsulation of threads in the Classes unit. This is VCL thread class: TThread
Using this class is also very simple. Most Delphi books say that the basic usage is: first derive your own thread class from TThread (because TThread is an abstract class and cannot generate instances), and then use the Override abstract method: Execute( This is the thread function, which is the part of the code executed in the thread). If you need to use the visual VCL object, you need to do it through the Synchronize process. For specific details, we will not go into details here. Please refer to relevant books.
The next thing this article will discuss is how the TThread class encapsulates threads, that is, an in-depth study of the implementation of the TThread class. Because only by truly understanding it can we use it better.
The following is the declaration of the TThread class in DELPHI7 (this article only discusses the implementation under the Windows platform, so all the code related to the Linux platform has been removed):
TThread = class
private
FHandle: THandle;
FThreadID: THandle;
FCreateSuspended: Boolean;
FTerminated: Boolean;
FSuspended: Boolean;
FFreeOnTerminate: Boolean;
FFinished: Boolean;
FReturnValue: Integer;
FOnTerminate: TNotifyEvent;
FSynchronize: TSynchronizeRecord;
FFatalException: TObject;
procedure CallOnTerminate;
class procedure Synchronize(ASyncRec: PSynchronizeRecord); overload;
function GetPriority: TThreadPriority;
procedure SetPriority(Value: TThreadPriority);
procedure SetSuspended(Value: Boolean);
protected
procedure CheckThreadError(ErrCode: Integer); overload;
procedure CheckThreadError(Success: Boolean); overload;
procedure DoTerminate; virtual;
procedure Execute; virtual; abstract;
procedure Synchronize(Method: TThreadMethod); overload;
property ReturnValue: Integer read FReturnValue write FReturnValue;
property Terminated: Boolean read FTerminated;
public
constructor Create(CreateSuspended: Boolean);
destructor Destroy; override;
procedure AfterConstruction; override;
procedure Resume;
procedureSuspend;
procedure Terminate;
function WaitFor: LongWord;
class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod); overload;
class procedure StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
property FatalException: TObject read FFatalException;
property FreeOnTerminate: Boolean read FFreeOnTerminate write FFreeOnTerminate;
property Handle: THandle read FHandle;
property Priority: TThreadPriority read GetPriority write SetPriority;
property Suspended: Boolean read FSuspended write SetSuspended;
property ThreadID: THandle read FThreadID;
property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
end;
The TThread class is a relatively simple class in Delphi's RTL. There are not many class members and the class attributes are very simple and clear. This article will only conduct a detailed analysis of a few more important class member methods and the only event: OnTerminate.
(to be continued)