To terminate the running of a thread, you can use the following methods:
1, the thread function returns (preferably using this method).
2. By calling the ExitThread function, the thread will undo itself (preferably not using the method).
3, the thread in the same process or another process calls the TerminateThread function (you should avoid using this method).
The 4, exitprocess, and terminateprocess functions can also be used to terminate the running of a thread (you should avoid using this method).
The following is a detailed description of how the terminating thread runs: 1-4, and what happens when the thread terminates running: 5.
1. The thread function returns
Threads should always be designed in such a way that they can return when they want the thread to terminate the run. This is the only way to ensure that all thread resources are properly purged.
If the thread can return, you can ensure that the following items are implemented:
(1) All C + + objects created in the thread function are correctly undone through their undo functions.
(2) The operating system will properly release the memory used by the thread stack.
(3) The system sets the thread's exit code (which is maintained in the thread's kernel object) as the return value of the threading function.
(4) The system will decrement the usage count of the thread kernel object.
2. ExitThread function
You can have the thread call the ExitThread function to force the thread to stop running:
Function Prototypes:
VOID ExitThread (DWORD dwexitcode);
This function terminates the running of the thread and causes the operating system to clear all operating system resources used by the thread. However, C + + resources, such as C + + class objects, will not be undone. For this reason, it is best to return from the thread function rather than by calling ExitThread.
Of course, you can use the ExitThread dwexitthread parameter to tell the system how to set the thread's exit code. The ExitThread function does not return any values because the thread has stopped running and cannot execute more code.
note the best way to stop a thread from running is to have its thread function return. However, if you use the methods described in this section, you should know that the ExitThread function is the function that Windows uses to undo a thread. You should never call ExitThread if you write a C + + code. You should use the Visual C + + Run-time library function _endthreadex. If you do not use Microsoft's Visual C + + compiler, your compiler vendor has its own exitthread substitution function. Whatever this substitution function is, it must be used.
3. TerminateThread function
Calling the TerminateThread function can also terminate a thread's operation:
Function Prototypes:
Copy Code code as follows:
BOOL TerminateThread (
HANDLE Hthread,
DWORD Dwexitcode);
Unlike ExitThread, ExitThread always undoes the calling thread, and TerminateThread can undo any thread. The Hthread parameter is used to identify the handle of the thread that is being terminated. When a thread terminates running, its exit code becomes the value you pass as the Dwexitcode parameter. Also, the usage count of the thread's kernel objects is decremented.
Note that the TerminateThread function is a function that runs asynchronously, that is, it tells the system that you want the thread to terminate, but when the function returns, the thread is not guaranteed to be undone. If you need to know exactly what the thread has terminated, you must call WaitForSingleObject or a similar function to pass the thread's handle.
A well-designed application never uses this function because a thread that is terminated cannot receive a notification that it has been revoked. Threads cannot be purged correctly and cannot prevent themselves from being undone.
Note When you undo a thread by using a method that returns or invokes ExitThread, the memory stack for that thread is also undone. However, if you use TerminateThread, the system does not undo the thread's stack until the process that owns the thread terminates running. Microsoft intentionally uses this method to implement TerminateThread. If other threads that are still executing are referring to the value on the thread stack that is forcibly undone, then other threads may have an access violation problem. If you leave the stack of a thread that has been undone in memory, other threads can continue to run well.
In addition, DLLs usually receive notifications when a thread terminates running. If you use TerminateThread to force the thread to terminate, the DLL does not receive notifications, which prevents proper cleanup.
4. Undo thread when process terminates run
The ExitProcess and TerminateProcess functions can also be used to terminate the running of a thread. The difference is that these threads will terminate all threads in the running process. In addition, because the entire process has been closed, all resources used by the process must have been purged. This, of course, includes the stack of all threads. These two functions cause the remaining threads in the process to be forcibly undone, just as they would call TerminateThread from each remaining thread. Obviously, this means that the correct application cleanup does not occur, that is, the C + + object Undo function is not invoked, the data does not go to disk, and so on.
5. Actions that occur when the thread terminates the runtime
When a thread terminates running, the following actions occur:
(1) All user objects owned by the thread are freed. In Windows, most objects are owned by the process that contains the threads that created the objects. But a thread has two user objects, that is, windows and hooks. When a thread terminates running, any windows are automatically undone and any hooks created or installed by the thread are unloaded. Other objects are undone only if the process that owns the thread terminates running.
(2) The exit code for the thread is changed from Still_active to code passed to ExitThread or TerminateThread.
(3) The state of the thread kernel object becomes notified.
(4) If the thread is the last active thread in the process, the system also treats the process as if it has terminated.
(5) The thread kernel object's usage count is decremented by 1.
When a thread terminates running, the kernel object is not automatically freed until all the closed references to the thread kernel object that it is associated with are shut down.
Once the thread is no longer running, there is no other thread in the system that can handle the thread's handle. However, other threads can call GetExitCodeThread to check whether the thread identified by Hthread has terminated. If it has stopped running, determine its exit code:
Function Prototypes:
Copy Code code as follows:
BOOL GetExitCodeThread (
HANDLE Hthread,
Pdword Pdwexitcode);
The value of the exit code is returned in the DWORD that Pdwexitcode points to. If the thread has not stopped running when GetExitCodeThread is invoked, the function fills the DWORD with the still_active identifier (defined as 0x103). Returns True if the function runs successfully.