Terminating a Thread and Thread Exit Codes

< BACK  NEXT >
[oR]

A thread terminates when the thread function exits. The return value from the thread function is the thread's exit code. The exit code can be used to communicate success or failure to other threads. A thread function, or any function it calls, can terminate prematurely by calling ExitThread. This function is passed a single DWORD parameter that is used as the thread's exit code:

 ExitThread(10); // set thread exit code to 10 

The code in Listing 5.8 creates a thread, and then calls WaitForSingleObject to block the primary thread until this thread terminates, or until 5000 milliseconds have elapsed. It is a good idea to set a timeout on waiting for a thread just in case the thread function fails. The thread function calls ExitThread to prematurely terminate the thread and set the exit code to 10. Note that the output message and the return statement will never be executed. Once WaitForSingleObject unblocks the function, GetExitCodeThread is called to retrieve the exit code (which should be 10). This function takes the thread handle and a pointer to a DWORD to receive the exit code.

Listing 5.8 Thread exit codes
 DWORD WINAPI MyThreadProc2(LPVOID lpParameter) {   ExitThread(10);   cout   _T("This message is not displayed")   endl;   return 0; } void Listing5_8() {   HANDLE hThread;   DWORD dwExitCode;   hThread = CreateThread(NULL, 0, MyThreadProc2,       NULL, 0, NULL);   if(hThread == NULL)     cout   _T("Could not create thread")   endl;   else   {     if(WaitForSingleObject(hThread, 5000)         == WAIT_FAILED)       cout   _T("Could not wait on thread")              endl;     GetExitCodeThread(hThread, &dwExitCode);     CloseHandle(hThread);     cout   _T("Thread Exit code: ")            dwExitCode endl;   } } 

A thread can be terminated by another thread through calling TerminateThread. This function is passed the kernel object handle of the thread to terminate, and a DWORD specifying the exit code to set for the thread.

 DWORD dwExitCode = 20; if(!TerminateThread(hThread, dwExitCode))   cout   _T("Could not terminate thread.")   endl; 

As with TerminateProcess, you should only use TerminateThread as a last resort. Dynamic Link Libraries may have allocated thread local storage (TLS, described later in the chapter), and the DLLs will not have the opportunity to free this resource.

Thread States

A thread can exist in one of the following states:

  • Suspended Thread is not executing and will be suspended indefinitely.

  • Running Thread is executing code.

  • Sleeping Thread is sleeping for a specified period of time.

  • Blocked Thread is waiting for an event to occur, usually when calling WaitForSingleObject.

  • Terminated Thread has terminated, but the thread exit code is still available.

The functions SuspendThread and ResumeThread are used to change a thread from running to suspended, and vice versa. A thread can suspend itself but cannot resume itself since it is not executing, and so cannot call ResumeThread.

In Windows CE versions prior to 3.0, the minimum time a thread could be put to sleep was around 25 milliseconds. In version 3.0 the Sleep function can sleep a thread for a period of 1 millisecond or greater. This is due to changes to thread scheduling described later in this chapter. Further, the GetTickCount function (which returns the number of milliseconds elapsed since the device was powered-on) provides a resolution down to a millisecond. In Listing 5.9 the primary thread is put to sleep for a single millisecond, and the amount of time spent sleeping is recorded. In Windows CE 3.0, the program will record that the thread was asleep for around two milliseconds (the sleep time, plus overhead of calling GetTickCount), whereas in Windows CE versions prior to 3.0, a value of around 25 milliseconds or more will be recorded.

Listing 5.9 Sleeps a thread
 void Listing5_9() {   DWORD dwTickCount = GetTickCount();   Sleep(1);   dwTickCount = GetTickCount()  dwTickCount;   cout   _T("Sleep for: ")   dwTickCount   endl; } 

You can pass the value "0" to the Sleep function, and this yields control back to the thread scheduler regardless of whether the thread's time quantum was up. This can be used to allow other threads with the same priority an opportunity to execute immediately. This can be useful when synchronizing threads.


< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net