Our aim is to write a simple concurrent C++ program using C++11 standard library. More precisely, we would like to write a program that executes two or more separate instructions at the same time.
What is a thread?
We use threads to write concurrent programs. But what is a thread? If you are looking over the internet, people have many answers to this question. Everyone has its own explanation, but I was not able to find a simple answer. Therefore, I will give my simple definition of threads (I don’t claim that it is the right one).
A thread is a set of instructions for a computer. When you execute the program, it creates the main thread. The program is concurrent, if the main thread spawns other threads.
Don’t worry if this doesn’t make any sense now. We will get better understanding about the threads through examples.
First concurrent program
We would like to have a program which does two different tasks – each in their own thread. As always, the main function will start the main thread. The main thread will spawn two additional threads, which will execute their tasks.
The first concurrent program
helloWorld.cpp is listed below.
We must compile it with C++ compiler which supports C++11 standard. Additionally, we must add the flags -pthread -std=c++11. For example, on Linux, the command looks like:
The output of the program is
Let’s explain it. We included
<chrono> libraries. First one allows us to write concurrent
programs and the second one is used for managing the time.
Then, there are two functions, which are quite similar. Both are iterating certain number of times. In each iteration, they print some information to standard output and then wait for 1 or 0.5 second.
The most interesting part is the main function. It creates two threads. Input
argument for a thread constructur is a function. The function will be executed
immediately in the thread. (
function_1 will be executed
thread_1.) Then the
member function is called. This forces current thread to wait for the other one.
thread_1.join() forces main thread to wait for the
thread_1 to finish.) If we don’t
our threads, we end up in the land of undefined behavior.
We used threads to write our first concurrent program. But using plain threads is considered a bad programming practice. However, my opinion is that it is good to know them because they are a basic building block of concurrent programs.
In the next articles we will describe how to pass a function with arguments to a thread and investigate why are the plain threads dangerous.