Creating an Object-Oriented Wrapper to Windows Threads

We will build a simple wrapper to basic threading facility provided by the windows operating system (Win32 subsystem). This article is only about worker threads. In the future articles, we shall discuss more about adding message pump to the thread to make it a User Interface thread, we shall also discuss using Thread synchronization primitives and thread pooling with comprehensive examples.

Thread Definition

Thread is a single path of execution in a process. Thread is also known as a lightweight process. It requires fewer resources than a process and executes within the address space of a process. There can be several threads running simultaneously within a process. Every operating system supports threads. A thread is usually defined by a function, which carries a predefined generic signature. When we create a thread with a function of this kind, then the function runs in a new path of execution.

Working with Windows Threads

We can request the operating system to create a thread for
us using the function call CreateThread,

Lets concentrate only on lpStartAddress and lpParameter for now. The parameter lpStartAddress has to be a pointer to function of type:

DWORD WINAPI ThreadProc(
LPVOID lpParameter // thread data
);

Rest of the parameters to CreateThread function will be ignored for now.

Our task is to build an object oriented wrapper class using these functions, since we know they are enough to create a thread.

Lets now create a class called ThreadClass. Every object of ThreadClass will represent a unique thread. Also it will have methods to create and manage that thread. It has to be noted that whenever we create a new thread, we get a process-wide identifier for that thread called Thread Handle. This handle will be useful for us in managing the thread. So, the threads handle will become an unavoidable member of the class. Apart from that, we will have a Boolean variable to indicate the state of the thread. Now our class looks like this.

One of the things that need explanation is the _ThreadFunc function. This is a friend function to the class. We will know about the details of this function later. This class has almost all the functions that are necessary to manage a thread. We will know the three virtual functions in the middle ThreadEntry, Run and ThreadExit very soon.

Lets now discuss about the friendly function; this function will be responsible for creating the illusion of thread as an object.

Now we know that this function is the actual thread of execution, lets see how to create the thread. This function just creates a new thread and stores the Id in m_hThread, which will be used to manage the thread. When this function is called, it calls the win32 function CreateThread with the address of _ThreadFunc function and passes the this pointer as the function parameter.

Now lets go back to the _ThreadFunc. This function after typecasting the parameter to ThreadClass type, calls ThreadEntry, Run and ThreadExit functions. Now in your derived class (from Thread), you will over-ride these three functions, so they get called. And bingo, there is our Thread class working.

Now to using our class, just the way you create an object of CWinThread, you will create an object of this class and call CreateNewThread and bingo, you have a new thread running for you. But remember to over ride the Run member function of this class.

Thus we have created a wrapper around windows threads and shielded the user from the intricacies of creating and using threads in the raw form. This class can be extended and used in the way as shown above.

don't terminate while GUI item is used in Run()

in general, this class is normal.but i write a counter in Run(), and Set counter to a window text.following code show this:
Run()
{
int i = 0;
while (true)
{
char buf[100];
wsprintf(buf, "%d", i);
SetWindowText(m_hWnd, buf);
if (m_Terminated)
break;
}
}

but i only write OutputDebugString instead of SetWindowText,
it is can exit normally. why?

Tracking multiple threads

I had the same problem, with a multithreaded program,
and used the returned handle from CreateThread, as well
as the ThreadID to track the threads. I saved them in an
array ( DWORD, same as Hndl ), and passed the thread
an index to this array in the lpParameter.

The threads can then identify themselves, and the
controlling program can access each thread using the
thread handle and/or threadID

TerminateThread does not destroy the stack

If a thread is terminated by TerminateThread(), The stack for that particular thread os released only when the process that owns it is terminated. This could also lead to access violation due to the following reasons

Some other thread might still be using pointers that reference data contained on the terminated thread's stack, if these other threads attempted to access the stack, an access violation could occur.

For more details kindly refer the book
"Advanced Windows Third Edition" by Jeffrey Richter

Top White Papers and Webcasts

Data integrity and ultra-high performance dictate the success and growth of many companies.
One of these companies is BridgePay Network Solutions, a recently launched and rapidly growing financial services organization that allows merchants around the world to process millions of daily credit card transactions. Due to the nature of their business, their IT team needed to strike the perfect balance between meeting regulatory-mandated data security measures with the lowest possible levels of latency and …

Migrating away from Windows Server 2003 is an investment in your organization's future, and there has never been a better time to begin the migration process. Take the next step to transform your datacenter by upgrading your server platform with leading edge Windows Operating Systems and SanDisk flash solutions.