Thread class in Delphi
Raptor [Mental Studio]
Http://eental.mentsu.com
Three
Say the constructor, then look at the analyte function:
Destructor TTHREAD.DESTROY;
Begin
IF (fthreadid <> 0) and not ffinished then
Begin
Terminate;
IF fcreateSuspended then
RESUME
Waitfor;
END;
IF fhandle <> 0 Then CloseHandle (FHANDLE);
Inherited destroy;
FFATALEXCEPTION.FREE;
REMOVETHREAD;
END;
Before the thread object is released, first check if the thread is still executed, if the thread is still in execution (the thread ID is not 0, and the thread end flag is not set), then call the Terminate process end thread. The Terminate process is just simply set the Terminated flag of the thread class, as follows:
Procedure tthread.terminate;
Begin
Fterminated: = true;
END;
Therefore, threads still must continue to execute the normal end, not to terminate the thread immediately, this should be noted.
Say there is a little question here: Many people have asked me, how to "immediately" terminate the thread (of course refer to thread created with TTHREAD). The result is of course not! The only way to terminate the thread is to let the Execute method execute, so in general, let your thread can terminate as soon as possible, you must constantly check the Terminated flag in a shorter time in the Execute method so that you can exit in time. This is a very important principle of designing thread code!
Of course, if you must "immediately" exit the thread, the TTHREAD class is not a good choice, because if you force the thread with an API, it will eventually cause the TTHREAD thread object to not be properly released, and Access Vioc appears when the object destructure. This situation you can only create threads with API or RTL functions.
If the thread is starting the suspended state, turn the thread into the running state, then call the Waitfor to wait, its function is to wait until the thread is completed. With regard to the implementation of WaitFor, it will be placed later.
After the thread is completed, turn off the thread handle (where Handle is existing in the case of normal thread is created), and the thread object created by the operating system is released.
Then call TOBJECT.DESTROY to release this object and release the captured exception object, and finally call the number of threads in the process of RemoveThread.
Other aspects regarding SUSPEND / RESUME and thread priority settings, not the focus of this article, no longer described. The other two focuses on this article are discussed below: SYNCHRONIZE and WAITFOR.
But before introducing these two functions, you need to introduce two other thread synchronization techniques: events and critical regions.
Events in Event are different from the events in Delphi. In essence, Event is actually equivalent to a global Boolean variable. It has two assignments: SET and RESET, equivalent to setting it to True or false. Check that its value is performed by WaitFor operation. Corresponding to the Windows platform, it is three API functions: setEvent, resetEvent, WaitForsingleObject (there are several APIs that implement Waitfor features, which is the simplest). These three are primitives, so Event can achieve the application of general Boolean variables that cannot be implemented in multithreading. The function of Set and Reset has already said, now, for the Waitfor's functionality:
The WaitFor function is to check if the state is a SET status (equivalent to true). If so, return it immediately, if not, wait it to change to the SET state, during the waiting period, call the WaitFor thread at the suspend state. In addition, Waitfor has a parameter for timeout setting. If this parameter is 0, it will not wait, return to the state of Event, if it is infinite, unlimited waiting until the SET status occurs, if it is a limited value, wait for the corresponding millisecond number After returning to the state of EVENT.
When Event is converted from the RESET state to the SET status, wakes up the thread that hangs due to WaitFor this Event, which is why it is called Event. The so-called "event" refers to "state transition". This "state conversion" information can be passed between the thread through Event.
Of course, a similar function can be implemented with a Boolean variable that is protected (see the critical area below), as long as a loop checks the code of this Boolean code instead of WaitFor. From the functional say, it will be found in actual use, such waiting will occupy a large number of CPU resources, reduce system performance, affecting the speed of execution of other threads, so it is not economical, sometimes it may even There will be a problem. So it is not recommended.
(to be continued)