Reprinted: TTHREAD class

zhaozj2021-02-16  59

TTHREAD class

Summary

This paper introduces the package and operational mechanism of the TTHREAD class in Delphi5 from the perspective of the analysis source code, introduces the advantages and disadvantages of the TTHREAD class.

Keywords: Delphi5, Tthread, Windows API

table of Contents

1 Overview

2. Analysis TTHREAD class

2.1 TTHREAD Advantages

2.2 TTHREAD packages and operational mechanisms

3. Conclusion

4. Acknowledgment

5. References

full text

1 Overview

According to the description of the Windows SDK document, the running entity in the Windows thread is the type: function threadfunc (parameter: Pointer): Integer's function (translated into a format of Delphi). But we all know that threads are encapsulated into a TTHREAD class in Delphi. Why is Delphi to encapsulate it into a class? How is DELPHI packaged? How can we fully utilize the advantages of both? This is what you need to introduce below.

2. Analysis TTHREAD class

2.1 TTHREAD Advantages

There are many advantages to the thread as a class. First it can clearly, secure boundary thread related local variables and processes related global variables. Class-object models to entities mapping relationships ensures that any variables in the category are local, declare any variables other than the class are globally. So the Execute function written in writing the new thread As long as you pay attention to the external variables of the class, the method can access, as for the internal variables, the method can be used without considering the problem of synchronization. The more important benefits of making thread packages is to write new threads. You can use inheritance to re-use the function of the parent class, this is really an exciting function.

2.2 TTHREAD packages and operational mechanisms

Since there are many benefits that make thread packages have become well, as a competent programmer will understand how Delphi is encapsulated into a class, there is no better package.

The TTHREAD class in Delphi5 is the statement:

{TTHREAD}

Ethread = Class (Exception);

TthreadMethod = procedure of object; tthreadpriority = (TPDE, TPLOWEST, TPLOWER, TPNORMAL, TPHIGHER, TPHIGHEST, TPTIMECRITI);

TThread = class private FHandle: THandle; FThreadID: THandle; FTerminated: Boolean; FSuspended: Boolean; FFreeOnTerminate: Boolean; FFinished: Boolean; FReturnValue: Integer; FOnTerminate: TNotifyEvent; FMethod: TThreadMethod; FSynchronizeException: TObject; procedure CallOnTerminate; function GetPriority: TThreadPriority; procedure SetPriority (Value: TThreadPriority); procedure SetSuspended (Value: Boolean); protected procedure DoTerminate; virtual; procedure Execute; virtual; abstract; procedure Synchronize (Method: TThreadMethod); property ReturnValue: Integer read FReturnValue write FReturnValue; property Terminated : Boolean read FTerminated; public constructor Create (CreateSuspended: Boolean); destructor Destroy; override; procedure Resume; procedure Suspend; procedure Terminate; function WaitFor: LongWord; property FreeOnTerminate: Boolean read FFreeOnTerminate write FFreeOnTerminate; property Handle: THandle read FHandle; property Priority: TTHReadpriority Read GetPriority Write S etPriority; property Suspended: Boolean read FSuspended write SetSuspended; property ThreadID: THandle read FThreadID; property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate; end; invisible form object specifically, TThread object is an instance with a thread (length and width Are 0), I called this form of thread. This threaded form has all objects of the TTHREAD class. TTHREAD is created in the constructor, if you create a threaded form, then add a thread count, and finally establish a threaded instance. Similarly, TTHREAD objects are destroyed, first reduce the thread count, and then determine if the count is 0, if it is destroying the threaded form.

Why build a threaded form? The answer is the need for synchronous functions in TTHREAD SYNCHRONIZE (). Thread objects Access to other VCL properties The synchronization mechanism of other threads is implemented through a message queue. When the thread function performs synchronize (), he sends a cm_execproc message to the thread form. Because the thread form is a form of the process (although it is not visible), the message to the thread form will enter the process message queue, and the characteristic of the serial processing of the message queue guarantees that there is no access conflict. This is a simple and effective solution. I don't know if anyone applies multithreading in the console program. If any, the TTHREAD class may not be suitable. In this case, the thread function is applied directly, or you write a new TNewThread class yourself. Delphi is declared a partial function ThreadProc outside the TTHREAD class. This function is the thread function called in Windows SDK, which is as follows:

function ThreadProc (Thread: TThread): Integer; var FreeThread: Boolean; begin try Thread.Execute; finally FreeThread: = Thread.FFreeOnTerminate; Result: = Thread.FReturnValue; Thread.FFinished: = True; Thread.DoTerminate; if FreeThread then Thread.free; endthread (result); end;

Delphi does not use the thread function as a member function of TTHREAD, I want to put ThreadProc in TTHREAD's procTected PROCTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTECTED You can see ThreadProc as a TTHREAD object as a parameter parameter. This ensures that the TTHRead object enters the stack of threads, and a TTHREAD object does not destroy the data of another TTHRead object. Of course, the thread that creates a thread can also access the data in the new thread, and the Terminate process is done. So TTHREAD data may be damaged by other threads. Therefore, external threads should access the threads to be careful. Terminate () is a relatively typical: external thread only writes, the internal thread is read only, and if the two threads are read and written, it can lead to logic confusion.

The TTHREAD class is not directly called the CreateThread () API function directly, but uses a BeginThread () function. I don't know why, the function does not have the corresponding Delphi Help document, just in the introduction of "TTHREADFUNC TYPE". It may be that Borland thinks that its parameters will be modified in the future. However, the parameters of this function and the CreateThread () API are exactly the same. This is an exciting place because BeginThread () has added an exception handling function that Windows API. Interestingly, Delphi is built in BeginThread () created a new thread function, and packaged the original thread function and parameters as a parameter for the new function. The definition of BeginThread in Delphi5 is as follows:

TYPE PTHREC = ^ TTHREADREC; TTHREADREC = Record Func: tthreadfunc; parameter: Pointer; End;

function ThreadWrapper (Parameter: Pointer): Integer; stdcall; asm CALL _FpuInit XOR ECX, ECX PUSH EBP PUSH offset _ExceptionHandler Delphi's exception mechanism // newly added MOV EDX, FS: [ECX] PUSH EDX MOV EAX, Parameter MOV FS: [ECX], Espmov ECX, [EAX] .tthreadRec.Parameter Mov Edx, [EAX] .tthreadRec.FREEMEM PUSH ECX PUSH EDX CALL _FREEMEM POP EDX POP EAX CALL EDX // Call the original thread function

XOR EDX, EDX POP ECX MOV FS: [EDX], ECX POP ECX POP EBP END

function BeginThread (SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: LongWord): Integer; var P: PThreadRec; begin New (P); P.Func: = ThreadFunc; P . Parameter: = parameter; ismultithread: = true; result: = CreateThread (SecurityAttributes, Stacksize, @threadwrapper, p, creeionflags, threadid);

It makes people feel that the SERCURITTRIBUTES and STACKSIZE parameters that TTHREAD class communicated when calling BeginThread, respectively, NIL and 0, so that BeginThread () uses the default security settings and default stack size when calling CreateThread (). For the meaning of these two parameters, please refer to the Windows SDK document.

3. Conclusion

Due to time rush, it is briefly introduced that I think that Delphi's help documentation is not explained. I don't know if you have any doubts or feel that I am not talking about, please let us know: zg@hzhistar.com. Please advise!

4. Acknowledgment

"In fact, you this article only applies to Delphi5, Delphi6 has changed the synchronous multi-threaded VCL control for synchronous multi-threaded Multi-threaded Multi-threaded approach. Other changes in the synchronous multi-threaded VCL controls. Place, I believe that you will find the source code. In addition, (maybe you already know) Delphi's document clearly explain, call BeginThread and EndThread to replace Win32API's CreateThread and ExitThread (in fact "Windows Core Programming" also pointed out It is a very important role of the specific reason to read the book. It is the very important role of Delphi, which calls BeginThread is to set the global variable ismultithread, because many of the running mechanisms of Delphi are True when this variable is true. Tastful is a thread safe, such as a getMem and FreeMem function. "- From" HGD "

The above friends gave me rigorous criticism and warm encouragement, I express my heartfelt thanks! If you give me your thoughts, I will write your name here. :) 5. Reference

1. "Windows Core Programming", Machinery Industry Press, May 2000 (although Chinese translation) 2. "Microsoft Platform SDK", Microsoft, Aug 2001 3. "Delphi 5.0 Help Document", Delphi 5.0 Source Code

转载请注明原文地址:https://www.9cbs.com/read-26542.html

New Post(0)