Creating a C++ Thread Class

Introduction

Recently, my brother asked me whether there was an easy way to create a C++ class that facilitated object orientated threading. I have written many multi-threaded libraries in the past; however, they are all in C. C has always been my language of choice for low-level programming; I use C++ for GUI development. Although there are many excellent examples of object-orientated threading on CodeGuru, none of the classes introduced suited all of my brother’s needs and my curiosities. He wanted a thread class that had the following attributes:

  • It supports both event driven and interval based asynchronous threading.
  • It supports both homogeneous and specialized threading.
  • It provides a FCFS (First Come First Serve) stack-queue for posting and handling multiple tasks.
  • It is portable.
  • It is simple to implement.

To support the new class, CThread, other supporting classes were also developed. These classes included the CMutexClass, CEventClass, and CTask classes. The CMutexClass and CEventClass provide resource management while the CTask class is a base class for deriving classes that support homogeneous asynchronous threading.

What Is Threading?

Every process has at least one thread of control and every process can perform at least one task at a time. A process that has more than one thread of control defines a multi-threaded process. A multi-threaded process allows multiple tasks to run asynchronously from within the environment of the process.

Resource Management—Thread Synchronization

Because threads within a multi-threaded process share the same resources, OS level control mechanisms are necessary to insure data integrity. A loss of data integrity occurs when one thread is modifying a variable while another thread is attempting to read it or two threads are attempting to modify the same variable at the same time. To prevent this scenario, the OS provides a Mutual Exclusion Object known in short as a mutex. In multi-threaded applications, mutexes, deployed programmatically, prevent multiple threads from accessing a single resource at the same time. When a thread needs access to a resource, it must first acquire a mutex. Once a thread has acquired a mutex, other threads attempting to acquire the same mutex are blocked and placed in a low-CPU usage wait state. Once a thread has completed data access, it releases the corresponding mutex; this allows other threads to acquire it and access the corresponding data.

Poor implementations of mutexes can result in resource starvation, also known as deadlock. Resource starvation occurs when one or more threads are competing for the same resource. Deadlock can also occur if a thread attempts to acquire a mutex twice.

Example

Thread A Thread B
Acquires mutex(1) to modify data item 1 Acquires mutex(2) to modify data item 2
Wants mutex(2) to view data item 2 Wants mutex(1) to view data item 1

Deadlock occurs in the example above because Thread A is blocked trying to acquire mutex(2), which is held by thread B. Thread B is blocked trying to acquire mutex(1) which is blocked by Thread A.

Like mutexes, condition variables, in UNIX, are another form of synchronization mechanism. Condition variables allow threads to rendezvous. They allow one thread to notify another that a change has occurred. In Windows, these are events.

Operating System Calls

The following table is a list of the various functions used to implement threading in the CMutexClass, CEventClass, CTask, and CThread classes.

Function OS Description Class Used in
CreateThread Windows Creates a Windows thread CThread
pthread_create UNIX – POSIX THREADS Creates a UNIX thread CThread
pthread_join UNIX – POSIX THREADS Waits for a UNIX thread to terminate CThread
pthread_attr_init UNIX – POSIX THREADS Sets a thread attribute structure to default CThread
pthread_attr_setstacksize UNIX – POSIX THREADS Sets the stack size value of the thread attribute structure CThread
WaitForSingleObject Windows Waits for an object to be signaled CThread, CMutexClass, CEventClass
CreateMutex Windows Creates a named or unnamed mutex CMutexClass
CloseHandle Windows Releases resources alloacate to a Windows handle CMutexClass, CEventClass, CThread
ReleaseMutex Windows Releases a prevously acquired mutex locked by WaitForSingleObject CMutexClass, CEventClass
pthread_mutexattr_init UNIX – POSIX THREADS Initializes a mutex attribute structure CMutexClass, CEventClass
pthread_mutex_init UNIX – POSIX THREADS Initializes a mutex using a provided attribute structure CMutexClass, CEventClass
pthread_mutex_lock UNIX – POSIX THREADS Locks a mutex CMutexClass, CEventClass
pthread_mutex_unlock UNIX – POSIX THREADS Unlocks a mutex previously locked by pthread_mutex_lock CMutexClass, CEventClass
pthread_mutex_destroy UNIX – POSIX THREADS Releases resources allocated to a mutex CMutexClass, CEventClass
CreateEvent Windows Creates a Windows event object CEventClass
SetEvent Windows Sets a Windows event object to signaled CEventClass
pthread_cond_signal UNIX – POSIX THREADS Unblocks a thread blocked on pthread_cond_wait CEventClass
pthread_cond_wait UNIX – POSIX THREADS Blocks on a condition variable CEventClass
pthread_cond_init UNIX – POSIX THREADS Initializes a condition variable CEventClass

More by Author

Must Read