# Synchronized multi-threading in C++ (No MFC!)

, 19 Apr 2007 BSD
 Rate this:
A C++ wrapper for Win32 multi-threading

## Introduction

Have you ever found multi-threading and thread synchronization difficult tasks in Win32? Then try these classes. Here I provide a small code library that will give you tools for creating multi-threaded applications in the C++ way, with out using MFC. If you have done multi-threading in Java and got fed up with the thread classes in MFC, you have come to the right place. Enough talking, I will take you right away through a step-by-step tutorial on using these classes.

## Background

You should be familiar with OOPs. You should also be familiar with terms like virtual functions, overriding, namespaces, exceptions etc. But you need not be a C++ guru.

## Using the code

First, I will give you the list of header files you should include in the CPP file that use my thread classes:

```#include <STRING>
using namespace std;

using namespace openutils;```

The next step is to create a customized `Thread` class from the base `Thread` class that you find in ou_thread.h:

```class MyThread : public Thread {
private:
int m_nCount;
public:
m_nCount = n;
}
void run() {
for(int i=0;i<m_nCount;i++) {
cout << getName().c_str() << ":" << i << endl;
}
}
};```

If you have done thread programming in Java, the above class will look familiar. First we have inherited publicly from the `Thread` class and then we gave our own implementation to the `run()` function. The `MyThread` class we just created has a private integer variable which is used by the `run()` function to print out the thread's name that much time. The `setName()` and `getName()` functions are derived from the base class.

Now let us create a `main()` function to test the `MyThread` class:

```int main() {
try {
t1->start();
t2->start();
t1->stop();
t2->stop();
printf("%s\n",ex.getMessage().c_str());
}
delete t1;
delete t2;
return 0;```

Here we created two thread pointers pointing to `MyThread` objects.

The `MyThread` constructor takes two arguments, value of the counter variable and the thread name. Then we start both these threads by calling the `start()` function, which in turn calls our implementation of `run()`. If the low-level thread creation was not successful, then the `try`-`catch` block will handle that problem gracefully.

When you run this program, you will get output much like the following:

```ThreThread 02:0
Thr:2
Th2:5
T02:8```

You can see that thread2 is executing the `run()` function before thread1 has finished and both threads execute together to produce a confusing result. This can be more serious if both threads are accessing a critical resource like a database file at the same time. This problem can be solved by using a Mutex object.

A Mutex is a synchronization object that allows one thread mutually exclusive access to a resource. We can create a mutex using the `Mutex` class and hand over its ownership to the first thread. The next thread can be made to "wait" until the first thread "releases" the ownership of that object. Let us see how this can be achieved.

First include the following declaration to the `main()` function just before calling `t1->start();`

`Mutex m("MyMutex");`

This will create a mutex object identified by the name `MyMutex`. We can use this object in the `run()` function to control access to shared code. Modify the `run()` function in `MyThread` class to include calls to `wait()` and `release()` functions:

```void run() {
wait("MyMutex");
for(int i=0;i<m_nCount;i++) {
cout << getName().c_str() << ":" << i << endl;
}
release("MyMutex");
}```

Please keep in mind that mutex names are case sensitive. If the mutex is not found, then `wait()` and `release()` functions will throw a `ThreadException`. Now recompile and run the program. You will see the following output:

```Thread 01:1

You can see how thread2 waits until thread1 is finished, to produce the desired output. Using mutexes has their own overhead and tends to slow down everything. So use them when only one thread at a time should be allowed to modify data or some other controlled resource.

If synchronized by a mutex, it is important to call `stop()` on all threads in the same order `start()` was called on them. If no mutex was used, you can avoid calling `stop()` on threads.

Call the `release()` function of mutex after the calls to `stop()` functions of the thread objects.

```t1->stop();
t2->stop();
m.release();```

Every thread has a base priority level determined by the thread's priority value and the priority class of its process. The system uses the base priority level of all executable threads to determine which thread gets the next slice of CPU time. Threads are scheduled in a round-robin fashion at each priority level, and only when there are no executable threads at a higher level does scheduling of threads at a lower level take place.

The `setPriority()` function enables setting the base priority level of a thread relative to the priority class of its process. This function can take any of the following values as its only argument:

 Priority Value Meaning `Thread::P_ABOVE_NORMAL` Indicates 1 point above normal priority for the priority class. `Thread::P_BELOW_NORMAL` Indicates 1 point below normal priority for the priority class. `Thread::P_HIGHEST` Indicates 2 points above normal priority for the priority class. `Thread::P_IDLE` Keeps this thread idle. `Thread::P_LOWEST` Indicates 2 points below normal priority for the priority class. `Thread::P_NORMAL` Indicates normal priority for the priority class. `Thread::P_CRITICAL` Puts the thread in the highest possible priority.

For example, the following code puts thread1 in a high priority:

`t1->setPriority(Thread::P_HIGHEST);`

By default, a thread is created with the `P_NORMAL` priority.

## Running the demo project

To run the demo project, create a Win32 console application in your Visual C++ IDE, add the demo project files to it and compile.

## History

• Created: October 14th, 2003
• Updated source: 9 July 2004

## Share

No Biography provided

 First PrevNext
 My vote of 5 arashmd 5-Jul-13 23:46
 My vote of 5 zssureqh 29-Aug-12 18:53
 My vote of 5 zssureqh 25-Aug-12 16:13
 Quick guide to make threads in C++ Jessn 16-Jan-12 0:44
 Thanks Member 4425889 20-Apr-10 11:02
 Two error checks are always false cjdunford 14-Nov-09 1:33
 You need to call CloseHandle after OpenMutex mgrcar 21-Jul-07 13:31
 Re: You need to call CloseHandle after OpenMutex maglev_tgv 12-Nov-07 18:30
 Compile error - cannot convert to LPCWSTR MEK3 5-Jun-07 21:14
 Re: Compile error - cannot convert to LPCWSTR MEK3 7-Jun-07 21:53
 Re: Compile error - cannot convert to LPCWSTR embtech 14-Jun-07 13:37
 Re: Compile error - cannot convert to LPCWSTR maglev_tgv 19-Nov-07 19:11
 Re: Compile error - cannot convert to LPCWSTR jk2l 30-Mar-08 14:48
 CString to double conversion problem? Vinod Moorkkan 19-Apr-07 21:41
 Re: CString to double conversion problem? frank.fang 25-Apr-07 0:18
 I get so many errors deville75 23-Jan-07 3:20
 ```c:\program files\microsoft visual studio\vc98\include\ios.h(146) : error C2872: 'streambuf' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(159) : error C2872: 'ostream' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(159) : error C2872: 'ostream' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(160) : error C2872: 'ostream' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(180) : error C2872: 'streambuf' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(207) : error C2872: 'streambuf' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(210) : error C2872: 'streambuf' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(219) : error C2872: 'ostream' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\streamb.h(90) : error C2872: 'streampos' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\streamb.h(90) : error C2872: 'streamoff' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\streamb.h(91) : error C2872: 'streampos' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\streamb.h(91) : error C2872: 'streampos' : ambiguous symbol c:\program files\microsoft visual studio\vc98\include\ios.h(258) : error C2872: 'ios' : ambiguous symbol .... And more like these from ostream.h as well ```   These are the errors I get. Am I missing something?   ------------------------ Impossible is Nothing
 Re: I get so many errors Vijay Mathew Pandyalakal 23-Jan-07 17:35
 Re: Linking Problem Vijay Mathew Pandyalakal 16-Aug-06 17:30
 Thread fails if "stop" not called mcd90 21-Apr-06 8:37
 Re: Linking error mcd90 20-Feb-06 7:57
 Re: Linking error Vijay Mathew Pandyalakal 20-Feb-06 17:53
 Re: Linking error mcd90 21-Feb-06 2:17
 Re: Linking error Vijay Mathew Pandyalakal 21-Feb-06 17:21
 An error when i add a sleep() in run() Surpaimb 21-Sep-05 23:57
 Re: An error when i add a sleep() in run() Vijay Mathew Pandyalakal 22-Sep-05 17:40
 Re: An error when i add a sleep() in run() Surpaimb 23-Sep-05 18:38
 AVOID to wait time-consuming tasks frank.fang 25-Apr-07 0:04
 Sequential in ATL Win Service Anonymous 6-Aug-05 4:14
 Error adding to my project buho_usp 2-Jun-05 9:15
 Re: Error adding to my project Vijay Mathew Pandyalakal 2-Jun-05 17:49
 Re: Error adding to my project Anonymous 4-Aug-05 12:47
 awesome! Sebastian Pipping 24-Mar-05 10:33
 Socket prog or threading Dablu 4-Feb-05 1:19
 Re: Bug - ExitThread() Vijay Mathew Pandyalakal 25-Oct-04 1:32
 Re: Bug - ExitThread() Vijay Mathew Pandyalakal 2-Jun-05 17:54
 Use WaitForSingleObject with caution! Volker von Einem 20-Jul-04 20:11
 Re: Use WaitForSingleObject with caution! bandanna2k 14-Feb-07 6:46
 So Good Hing 14-Jul-04 16:03
 Slice of CPU time Pablez 18-Feb-04 21:16
 Re: Slice of CPU time John M. Drescher 13-Jul-04 8:50
 The dinning philosopher's problem using threads ignacio nacho 18-Feb-04 13:43
 Last Visit: 31-Dec-99 18:00     Last Update: 20-Oct-14 0:00 Refresh 12 Next »