Chapter: Multicore Application Programming For Windows, Linux, and Oracle Solaris - Windows Threading

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail

Terminating Threads

Although there are multiple ways to cause a thread to terminate, the recommended approach is for the thread to exit the function that it was instructed to run. In Listing 6.6, the thread will print out its ID and then exit.

Terminating Threads

 

Although there are multiple ways to cause a thread to terminate, the recommended approach is for the thread to exit the function that it was instructed to run. In Listing 6.6, the thread will print out its ID and then exit.

 

Listing 6.6     Printing Thread ID and Exiting

DWORD WINAPI mythread( __in         LPVOID lpParameter )

 

{

 

printf( "Thread %i \n", GetCurrentThreadId() ); return 0;

}

It is also possible to cause threads to terminate using the call ExitThread() or TerminateThread(). However, these are not recommended because they may leave the application in an unspecified state. The thread does not get the opportunity to release any held mutexes or free any other allocated resources. They also do not give the run-time libraries the opportunity to clean up any resources that they have allocated on behalf of the thread.

 

As long as care is taken to ensure that resources the thread has acquired are appropri-ately freed, a thread may terminate with a call to _endthread() or _endthreadex(). This call needs to match the call that was used to create the thread. If the thread exits with a call to _endthreadex(), the handle to the thread still needs to be closed by another thread calling closeHandle().

 

In a fork-join type model, there will be a master thread that creates multiple worker threads and then waits for the worker threads to exit. There are two routines that the master thread can use to wait for the worker to complete: WaitForSingleObject() or WaitForMultipleObjects(). As indicated by their names, these two routines will wait either for the completion of a single thread or for the completion of an array of threads. The routines take the handle of the thread as a parameter together with a timeout value that indicates how long the master thread should wait for the worker thread to com-plete; usually the value INFINITE will be appropriate. Listing 6.7 shows the code neces-sary to wait for a single thread to complete.

 

Listing 6.7     Using WaitForSingleObject()

#include <windows.h> #include <process.h>

 

unsigned int __stdcall mywork( void * data )

 

{

 

printf( "Thread %i\n", GetCurrentThreadId() ); return 0;

 

}

 

 

int _tmain( int argc, _TCHAR* argv[] )

 

{

 

HANDLE h[2];

 

for (int i=0; i<2; i++)

 

{

 

h[i] = (HANDLE)_beginthreadex( 0, 0, &mywork, 0, 0, 0 );

 

}

 

for (int i=0; i<2; i++)

 

{

 

WaitForSingleObject( h[i], INFINITE );

 

CloseHandle( h[i] );

 

}

getchar();

 

}

 

 

Listing 6.8 shows the equivalent code using WaitForMultipleObjects(). The first parameter to the function call is the number of threads that are to be waited for. The second parameter is a pointer to the array of handles to these threads. The third parame-ter is a boolean that, if true, indicates that the function should return when all the threads are complete or, if false, indicates the function should return on the comple-tion of the first worker thread. The final parameter is the length of time that the master thread should wait before returning anyway. Listing 6.8 shows an example of calling this.

 

Listing 6.8     Using WaitForMultipleObjects()

 

int _tmain( int argc, _TCHAR* argv[] )

 

{

 

HANDLE h[2];

 

for (int i=0; i<2; i++)

 

{

 

h[i] = (HANDLE)_beginthreadex( 0, 0, &mywork, 0, 0, 0 );

 

}

 

WaitForMultipleObjects( 2, h, true, INFINITE );

 

for (int i=0; i<2; i++)

 

{

 

CloseHandle( h[i] );

 

}

 

getchar();

}

Even after a thread created by a call to _beginthreadex() has exited, it will con-tinue to hold resources. These resources need to be freed by calling the CloseHandle() function on the handle to the thread. Listing 6.9 shows the complete sequence of creat-ing a thread, waiting for it to complete, and then freeing its resources.

 

Listing 6.9     Complete Thread Life Cycle

int _tmain( int argc, TCHAR* argv[] )

 

{

 

HANDLE handle;

 

handle = (HANDLE)_beginthreadex( 0, 0, &routine, 0, 0, 0 );

 

returnvalue = WaitForSingleObject( handle, INFINITE );

 

CloseHandle( handle );

 

return 0;

 

}

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.