C++ Multithreading Tutorial

In this tutorial we’ll discuss one of the more advanced programming concepts, C++ Multithreading and Concurrency.

Proper Multithreading support in C++ was introduced in the C++ 11 version. So if you are still using an older version, then be sure to update. Before C++ 11, we had to use the <pthread> library, which used POSIX.

With C++ 11 however, we now have a powerful yet simple library called <thread>. std::thread is the Class representing threads, out of which we create objects to create additional threads. By passing in the proper parameters, you have these threads execute commands and functions.


Understanding C++ Multithreading

Multithreading is often treated as a complex and difficult topic, and for good reason. Like any important topic however, proper usage and proper understanding will make things infinitely easier.

Uptil now, you’ve been executing all your code on a single thread. However, this is often far too slow, hence we have introduced the concept of multi-threading. To summarize, it’s basically the concept of using Multiple threads, each running independently of each other, but all running in parallel to complete a task(s).

While creating and launching simple threads is an easy task, managing 3 – 4 threads working in parallel, without interfering with each other, yet working alongside each other is a much harder task.


What is Thread?

By now we’ve mentioned the word “thread ” several times. A thread is like a “virtual” core. For the purpose of this article, you need to maintain this line of thinking. Think of each thread as a separate processing unit that can execute a program. And adding more threads into your program gives you more processing units to work with.

Here’s a little diagram we came up with to help you understand threads and multithreading. It’s a very simplified version, but it explains the basic principle behind multithreading. Each circle represents a thread and each rectangle represents a task that will take a minute to perform..

C++ Multithreading with threading Tutorial

Realistically, things are significantly more complicated. Things like “dependencies” come into play, where a Task-B may depend on Task-A begin completed before it can begin. As a result, threading will not benefit us in this situation as Task-A and Task-B cannot be executed at the same time on different threads.


Creating a C++ Thread

Now on to actually creating a Thread in C++. It’s fairly simple, and just requires a single line of code. Below is the syntax.

We just need to create a thread object, where the first parameter is the name of the function you want executed on the thread. If the function has any parameters, they are passed in as additional parameters in the thread object’s constructor.

#include <iostream>
#include <thread>
using namespace std;


void display(int x) {
    cout << "Executed on Thread: " << x << "\n";
}


int main() {
    thread t1(display, 1);
}

But wait, attempting to run this code would give us an error. (Shown below)

Executed on Thread: 1
terminate called without an active exception

What is the reason behind this? The reason is that even though the main thread has been closed (once the main function reaches it’s end), the thread has not been closed.

In short, we need to “join” both the Main threads and the other thread(s) before the program exits.


Joining Threads

The join() method can be thought of like this. The program started out with one thread, and must end that way. It’s similar to how several people may split up tasks to complete a project, but “join” back together at the end.

We can correct the previous code by simply adding a line, calling the join() method on our thread object.

#include <iostream>
#include <thread>
using namespace std;


void display(int x) {
    cout << "Executed on Thread: " << x << "\n";
}


int main() {
    thread t1(display, 1);

    t1.join();
}

Another handy feature is the isJoinable() method. This returns True or False, depending on whether the Thread is currently joinable or not.


Where can Multithreading be used?

One interesting example where I have often required the use of multithreading, is while taking input from the User. When using cin, the entire thread is basically waiting for the user to input some data and then press enter. The execution of the code will not proceed until this is done.

This can be quite problematic in applications that require some code that needs to be executed regularly. For example, I once created a Chat application, where two users could communicate over a local network through the console.

I faced a problem, where while one user was inputting text to be sent, the code responsible for retrieving data was not being executed. In short, until one message was sent, the message from the other user would not be displayed.

In order to solve this, I used C++ Multithreading, creating a separate thread responsible for constantly checking for incoming messages from the other user. To summarize, there were two threads, one for receiving and one for sending.


C++ Multithreading Example

Below is a small example to try and help cement the concept of multithreading in C++. It doesn’t have a lot of practical purpose, but it demonstrates properly the benefit of multithreading.

In a separate thread, I have created an infinite loop that checks for Key Presses, “A” and “Q” (GetKeyState is a Windows specific command). Now even though in the main thread we will be locked into entering data into the cin stream, key presses will still be detected by the other thread.

Try running this code for yourself and see the magic.

#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;


void display(int x) {
    while (1) {
        if(GetKeyState('A') & 0x8000)
        {
            cout << "A has been pressed" << endl;
        }
        else if (GetKeyState('Q') & 0x8000) {
            cout << "Q has been pressed" << endl;
        }
    }
}


int main() {
    thread t1(display, 1);
    string data;

    cout << "Enter some Data: ";
    cin >> data;
    t1.join();
}

This marks the end of the C++ Multithreading Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments