Win32 Threads.

Support for threading is one of the most useful concepts in the windows operating system. Threading is like steroids for application. It can boost performance of an application drastically. This performance boost is the result of a team work within an application. The main application will divide jobs which do not require any special attention to threads. Each thread will have a job to complete. These threads work in 'parallel' to make the application run fast.

AfxBeginThread is the magic function you need to spawn threads from your program. Typically the call for the AfxBeginThread will be like AfxBeginThread (ThreaFunc, Param). ThreadFunc is the function which acts as the thread. Param is the additional information you may need to pass to the thread. NULL is sufficient in case you don’t have information to pass


Warning: If you pass a local variable to the thread function. Possibilities are there that the variable may go out of the scope before the thread function exits. It is best to pass a pointer to dynamically allocated memory or make the creating thread wait for the new thread to terminate.This synchronization is possible by Events.

You can also have a member function to act as a thread. The only requirement is that you should declare the member function as static with the signature same as Threadfunc.


Normally the two parameters mentioned above are enough to bring a thread into life. In case, if you need more customization over the thread AfxBeginThread will also take arguments such as,


nPriority = The priority of the thread. An high priority thread is always scheduled CPU time before low priority thread. The default value for this property is
THREAD_PRIORITY_NORMAL. Any thread with priority above this value will eat most of the cpu time than other threads with normal priority.

nStackSize = The maximum stack size the thread can possesses. 0 indicates the thread can receive a minimum of 1 MB in the much larger 4GB address space.

dwCreateFlags= Two values can be given. Default is 0 which means thread will start its activity as soon as it created. If CREATE_SUSPENDED is used the thread will be created but in a suspended mode. It will only get activated when CWinThread::ResumeThread is called.We can suspend and resume a thread whenever we want to, for this purpose the MFC's thread management class CWinThread have functions such as SuspendThread() and ResumeThread(). Whenever SuspendThread is called a counter is incremented for that particular thread. The counter value is reduced by one when CWinThread::ResumeThread() is called. The thread will only resume its activity only when the counter value hit 0.

Different ways are there to cease a thread's activity depending on from where you want to terminate the thread. If you want to close a thread within a thread, you would be using ExitThread().Normally,this function is called when the thread finishes it job and returns.TerminateThread() is another function which you can use to stop a thread from outside of the thread function. Usually TerminateThread() is used on occasions when there is no other alternative . TerminateThread have following side-effects (as per MSDN) that may take your program down.

* If the target thread owns a critical section, the critical section will not be released.

* If the target thread is allocating memory from the heap, the heap lock will not be released.

* If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's
process could be inconsistent.

* If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

The most preferred way of terminating a thread from the outside is using Event object notification.

An event is something which signals the completeness of an activity.

HANDLE hKillEvent;

UINT Threadfunc(LPVOID pParam)

{

int iCount =(int)pParam;

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

SetEvent(hKillEvent);



for ( i =0; i<100; i++) // This won't execute.
;

return 1;

}

void SomeFunction()

{
int i =100;
hKillEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
::AfxBeginThread(Threadfunc,(LPVOID)i);
WaitForSingleObject(hKillEvent,INFINITE);

}

In the above function an event is created using the function CreateEvent(). The third parameter sets the initial state of the event. I have set it to FALSE to make the event non-signaled. An event can signaled by using the function SetEvent(HANDLE). WaitForSingleObject returns immediately when the event it is listening to is signaled.

Comments

Popular Posts