Writing Your First Multithreaded Program in C++
Multithreading is one of the most fascinating feature of modern day programming. If you are not familiar with multithreading then most probably you have been writing programs that are single threaded. By single threaded program we mean such a program where program instructions run in a sequence and at one time only single piece of program code is being processed by the processor.
In the inception stages and computing, single threaded programs were written because hardware need to run multithreaded programs was not available. With the evolvement of hardware technologies and advent of multicore processor, programming style also changed and multithreaded programs were introduced. You would have heard the terms dual core, quad core etc. Core basically refers to part of the processor that can run in parallel with each other. Quad core and dual core systems are often called multiprocessing systems because they are able to process multiple processes at a time.
Before dwelling into the details of multithreading, some important differences need to be explained here. Multitasking, Multiprocessing and Multithreading, these three terms are often interchangeable used but they are actually different.
Multitasking is basically doing multiple computing tasks at a time. Multiprocessing and multithreading are actually types of multitasking.
A process in operating system is basically a program. Multiprocessing means, running multiple processes on the same machine in parallel. For example, you are viewing this content on your web browser or may be through some other application. At the same time, you might be listening to some songs on some media player application or running some chat application in parallel to the browser. This is called multiprocessing, where multiple programs run in parallel. In the earliest of the computer systems, you could only run single application on your systems.
Now coming towards our; Multithreading is fine-grained form of multiprocessing. In multiprocessing, we run multiple programs in parallel; in multithreading we run different pieces of same program in parallel. I often use MS Word example to explain multithreading. You would have noticed that while you are typing on MS Word application, it automatically highlights spelling mistakes while writing and suggests you the corrections. What actually happening is that there are multiple threads running in parallel. One thread is responsible for typing data into your document, one thread is continuously checking spelling and grammar mistakes that you make and one thread is suggesting you possible spellings. There can be other threads running in parallel which are hidden to us. The point here is, that we are running a single MS Word application and different pieces of code of this program are executing in parallel. This is what we call multithreading. A thread is often referred to as the smallest unit that can be executed by processor.
If you have not been long at it, multithreading is not a simple concept to learn. There are lots of factors that come into play while multithreaded applications are being run, however, luckily enough, our operating system hides those from us and we only have to interact with application programmer’s interface in order to develop multithreaded applications in C++.
We will see how we can do it, in next section.
Multithreaded programs can be created in various ways. In C and some of the older versions of C++ language, POSIX framework was used for developing multiprogramming applications. However, POSIX fostered, older programming style and its compilation entailed several complex features and functions to be performed. We require a threading framework that allows us to visually write multithreaded code that can be debugged using some IDE like visual studio. . In short we need something like #include <thread> that we can insert on top of our code and sit back and enjoy the built in concurrency features of C++. Some third party vendors have provided such threading libraries that need to be incorporated in the IDE to utilize multithreading functionality. Two of these libraries are boost thread and just threads. Just thread is a commercial thread library and you need to pay for it.
The C++11 for Multithreading
We discussed that we need some threading library that can be incorporated in some IDE and is also free. Good news is that Microsoft introduced latest version of C++ programming language called C++11. In this newer version of the C++, several advanced features were introduced. A built in thread class library was also introduced with it. Now you can simply include #include <thread> into your programs and can utilize thread class concurrency features. An important thing to note here is that, C++11 is not available with Visual Studio 2010. You will have to upgrade to Visual Studio 2012 in order to utilize the functionalities of C++11.
Now let us come to some coding. With the help of a simple example, I will show you how can you create and run a thread in parallel with the main function execution. First look at the code in Example1 and try to understand what is happening there. I will explain it later.
Note: All the code sample in this article are written in Visual C++11 with Visual studio 2012 as the IDE.
Next, we have simply created a method called thread_method(). Function is often called method in some of the more advanced languages such as JAVA and C Sharp. Remember, whenever we want to create a new thread that we want to run in parallel, we will define a new function. In other words, if we want a certain piece of code to run in parallel with some other code, we need to place that code in a function. What actually happens is that function is run in a separate thread. Here in Example1, we have defined a function which simply displays that this function is being run in a separate thread parallel to the main function. You must be wondering, how come the main thread runs in a thread. Actually main thread is also running in a thread that compiler creates by default. We don’t need to write code to place main function in a separate thread because in uni-threading applications we don’t need to create thread and one thread is enough for us to achieve our desired functionality.
Next we have created a thread class using the statement
Next we are coming to a very important and crucial concept of thread. The join function of the thread class. Note that in Example1 we have called t.join() on the thread ‘t’. What it actually does is, it says to the parent thread which is main thread in this case that please wait, until I complete my execution.
Since, both the parent and child are running in parallel, therefore a parent can complete its execution before the child function. For instance, it can happen that main function thread completes its execution and program terminates before the child thread is completed. In such cases, child thread will also be terminated. By using join, we prevent this scenario. Join call from the child thread inside the parent thread actually requests the parent to wait until child completes its execution and then terminates.
You must be thinking, since both main function and thread_method() are now executing in parallel, which of the two display statements in each functions will be displayed first. Before answering this question let us move to our next Example2 where this question will be answered with more concrete explanation. For now, just look at the output of the Example1. If the output is different on your systems, do not worry.
In Example1 we only created one thread; therefore we had 2 threads in total. A main function thread and thread_method() function thread. In our next example we will create 10 threads and will pass the same thread_method() to each of the thread and will see the behavior of the execution of these threads. Look at Example2.
As the loop executes, the memory address of each created thread will be stored in the thread array using this line
Now we have ten threads and we will have to call join on each of these threads, therefore we have again executed a for loop and have traversed the thread array. We then executed join on each of the threads in the thread array using this line
|All times are GMT +5.5. The time now is 00:06.|