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,

HANDLE CreateThread(
 LPSECURITY_ATTRIBUTES lpThreadAttributes, // Security Descriptor
 DWORD dwStackSize,                        // initial stack size
 LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
 LPVOID lpParameter,                       // thread argument
 DWORD dwCreationFlags,                    // creation option
 LPDWORD lpThreadId                        // thread identifier
Lets concentrate only on lpStartAddress and lpParameter for now. The parameter lpStartAddress has to be a pointer to function of type:
  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.
class ThreadClass 
 virtual ~ThreadClass(){Kill();}

 //Thread Management
 bool CreateNewThread();
 bool Wait(); //Wait for thread to end
 bool Suspend(); //Suspend the thread
 void Resume(); //Resume a suspended thread
 bool Kill(); //Terminate a thread
 bool IsActive(); //Check for activity

 //override these functions in the derived class 
 virtual void ThreadEntry(){ }
 virtual void ThreadExit(){ }
 virtual void Run(){ }

 //a friend
 friend DWORD  WINAPI _ThreadFunc(LPVOID  pvThread);

 HANDLE m_hThread; //Thread handle
 bool m_bActive; //activity indicator
 DWORD m_lpId; //Thread ID

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.

//Friend of Thread class
//Actual thread around which the OO wrapper is built.
//Do not call twice on the same object.
//do something (initializing and finalizing) in ThreadEntry and ThreadExit functions.
DWORD  WINAPI _ThreadFunc(LPVOID  pvThread)
 ThreadClass* pThread = (ThreadClass*)pvThread;  //typecast

 pThread->ThreadEntry(); //initialize
 pThread->ThreadExit(); //finalize

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.

bool ThreadClass::CreateNewThread()
 m_hThread = CreateThread(NULL, 
                          (LPVOID) this, 
                          (LPDWORD) &m_lpId);

 if(m_hThread == NULL)
  return false;

 bActive = true;
 return true;

bool ThreadClass::Suspend()
 bActive = false;
 return(-1 != SuspendThread(m_hThread));//win32 API         

bool ThreadClass::Kill()
 return BOOL TerminateThread(m_hThread, 1); //win32 API
bool ThreadClass::Resume()
 bActive = true;
 return(-1 != ResumeThread(m_hThread)); //win32 API

bool ThreadClass::Wait()
 return (WAIT_OBJECT_0 
         == WaitForSingleObject(m_hThread, INFINITE)); 
 //win32 API

bool ThreadClass::IsActive()
 return m_bActive;

The above class doesnt use any of the synchronization primitives.

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.

class MyThread :: public ThreadClass
 virtual void ThreadEntry()

 virtual void ThreadExit()

 virtual void Run()
  //do something

 MyThread newThread;

 //One Some condition

 //Some other condition

 //An Exception?


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.


  • More concessions with herveleger, more stagger!

    Posted by wellslifkps on 03/23/2013 04:46pm

    herve leger outlet herve leger outlet herve leger outlet herve leger outlet herve leger outlet herve leger outlet herve leger outlet iphone 4s for sale cheap iphone 5 for sale refurbished iphone for sale

  • Works for me

    Posted by musanim on 05/20/2006 06:41pm

    Just what I needed; simple, worked first time (once I corrected the syntax and typos); thanks!

  • Switching too soon

    Posted by Legacy on 04/29/2003 12:00am

    Originally posted by: Maxxus

    I wrote something very similar but my fear is that the CPU will switch and start another thread before the first one has a chance to exit the _ThreadFunc(). Is there a chance of this?

  • Namaskar

    Posted by Legacy on 08/06/2002 12:00am

    Originally posted by: Robert

    I think we should speak english.


  • Namaste Satya Narayan Pandurang

    Posted by Legacy on 06/18/2002 12:00am

    Originally posted by: Susheelchandra Dive

    Hi Satya,
    Pleased to See ur name on the web page.
    Mee pthread library cha vapar karnyasathi concrete examples shodhat ahe. Please provide me any links if you know.

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

    Posted by Legacy on 12/21/2001 12:00am

    Originally posted by: chenyong

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

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

  • ThreadID vs Thread Handle

    Posted by Legacy on 12/04/2001 12:00am

    Originally posted by: A. Fortin

    How to get a thread handle, knowing the thread ID (from Thread32Next() function)?

  • Tracking multiple threads

    Posted by Legacy on 08/04/2001 12:00am

    Originally posted by: Jack Swann

    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

    HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes, // Security Descriptor
    DWORD dwStackSize, // initial stack size
    LPTHREAD_START_ROUTINE lpStartAddress, // thread function
    LPVOID lpParameter, // thread argument
    DWORD dwCreationFlags, // creation option
    LPDWORD lpThreadId // thread identifier

  • TerminateThread does not destroy the stack

    Posted by Legacy on 05/23/2001 12:00am

    Originally posted by: T.N Arvind

    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

  • Re: Current Thread State

    Posted by Legacy on 04/12/2001 12:00am

    Originally posted by: Sathya

    You can find out the current state of the thread by using

    DWORD WaitForSingleObject(
    HANDLE hHandle, // handle to object to wait for
    DWORD dwMilliseconds // time-out interval in milliseconds

    This function returns with exit code WAIT_OBJECT_0, if the thread is currently in the signalled state. Otherwise it will return you a WAIT_TIMEOUT result.

  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As the mobile enterprise marketplace expands and customer needs grow more diverse, Samsung recognizes that solution partners and developers play an essential role by continually innovating to meet their customers' needs. Samsung works to provide these developers and partners with the latest tools and resources needed to create these solutions. Read this program guide to learn how the Samsung Enterprise Alliance Program provides partners and developers with Samsung enterprise software development kits (SDKs) …

  • Thanks to the Internet of Things (IoT), physical assets are turning into participants in real-time global digital markets. The countless types of assets around us will become as easily indexed, searched and traded as any online commodity. While some industries will be tougher to transform than others – those with physical limitations, such as manufacturing, will be harder to digitize – untold economic opportunities exist for growth and advancement. Our research shows this will create a new "Economy …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date