Книга: Microsoft Windows Embedded CE 6.0 Exam Preparation Kit

Creating, Exiting, and Terminating Threads

Creating, Exiting, and Terminating Threads

The CreateThread function used to create a new thread expects several parameters that control how the system creates the thread and the instructions that the thread runs. Although it is possible to set most of these parameters to null or zero, it is necessary to provide at least a pointer to an application-defined function that the thread is supposed to execute. This function typically defines the core processing instructions for the thread, although you can also call other functions from within this function. It is important to pass the core function as a static reference to CreateThread because the linker must be able to determine the core function's starting address at compile time. Passing a non-static function pointer does not work.

The following code listing is copied from the Explorer.cpp file that you can find in the %_WINCEROOT%PublicShellOAKHPCExplorerMain folder. It illustrates how to create a thread.

void DoStartupTasks() {
 HANDLE hThread = NULL;
 // Spin off the thread which registers and watches the font dirs
 hThread = CreateThread(NULL, NULL, FontThread, NULL, 0, NULL);
 if (hThread) {
  CloseHandle(hThread);
 }
 // Launch all applications in the startup folder
 ProcessStartupFolder();
}

This code specifies FontThread as the new thread's core function. It immediately closes the returned thread handle because the current thread does not need it. The new thread runs parallel to the current thread and implicitly exits upon returning from the core function. This is the preferred way to exit threads because it enables C++ function cleanup to occur. It is not necessary to explicitly call ExitThread.

However, it is possible to explicitly call the ExitThread function within a thread routine to end processing without reaching the end of the core function. ExitThread invokes the entry point of all attached DLLs with a value indicating that the current thread is detaching, and then deallocates the current thread's stack to terminate the current thread. The application process exits if the current thread happens to be the primary thread. Because ExitThread acts on the current thread, it is not necessary to specify a thread handle. However, you must pass a numeric exit code, which other threads can retrieve by using the GetExitCodeThread function. This process is useful to identify errors and reasons for the thread exiting. If ExitThread is not explicitly called, the exit code corresponds to the return value of the thread function. If GetExitCodeThread returns the value STILL_ACTIVE, the thread is still active and running.

Although you should avoid it, there can be rare situations that leave you no other way to terminate a thread except for calling the TerminateThread function. A malfunctioning thread destroying file records might require this function. Formatting a file system might need you to call TerminateThread in debugging sessions while your code is still under development. You need to pass the handle to the thread to be terminated and an exit code, which you can retrieve later by using the GetExitCodeThread function. Calling the TerminateThread function should never be part of normal processing. It leaves the thread stack and attached DLLs behind, abandons critical sections and mutexes owned by the terminated thread, and leads to memory leaks and instability. Do not use TerminateThread as part of the process shutdown procedure. Threads within the process can exit implicitly or explicitly by using the ExitThread function.

Оглавление книги


Генерация: 1.099. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз