C++ Thread (1)

chuuuing
3 min readAug 21, 2021

--

We already discussed the difference between Thread and Process. Today let’s discuss more details about Thread, and run a sample code.

Example 1: Easiest Thread

After C++ we can use thread class by #include<thread>. And this is the function we want to run in our new thread:

#include<thread>
#include <iostream>
void playGame(int hour) {
for (int i=0; i< hour; i++) {
std::cout<< "played "<<i<<" hour.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}

STEP 1

Now to create a thread object, we simply pass the function we want to execute in the new thread object.

int main() {
int hour = 0;
std::thread my_thread(playGame, hour); // STEP 1

return 0;
}

Notice:

  • playGame is an callable: could be (1) function pointer, (2) function object or (3) lambda expression
  • hour is a parameter to pass to the function playGame, there could be more than one parameter

Once my_thread is created, the callable start running.

STEP 2

While we have the new thread mythread, in a certain time in the future, we do want to comeback to our main thread. But we need to first wait until mythread has done its job.

int main() {
int hour = 0;
std::thread my_thread(playGame, hour); // STEP 1
my_thread.join(); // STEP 2
printf("swap back to main");
return 0;
}

std::thread::join() will wait until is done, then swap back to main thread.

Thats it. Final code looks like this:

#include<thread>
#include <iostream>

void playGame(int hour) {
for (int i=0; i< hour; i++) {
std::cout<< "played "<<i<<" hour.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}

int main() {
int hour = 0;
std::thread my_thread(playGame, hour);

my_thread.join();
printf("swap back to main");

return 0;
}

Output:

played 1 hour.
played 2 hour.
swap back to main

Example 2: Why use it at all?

In one sentence: in ideal case, multithread helps your program to speed up with concurrency mechanism. The following example will show how the concurrency works:

Image you are playing game while listening to music, and your dinner is in the oven.

#include<thread>
#include <iostream>

// 1. callable = function pointer
void playGame(int hour) {
for (int i=0; i< hour; i++) {
std::cout<< "Task 1: played "<<i<<" hour.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
// 2. callable = function object
class Dinner {
public:
void cook(std::string name, int hour) {
for (int i=0; i<hour; i++) {
std::cout<<"Task 2: dinner "<< name << " is baked for "<< i <<"hour. \n";
}
}
};

// 3. callable = lambda expression
auto music = [](int count) {
for (int i = 0; i < count; i++) {
std::cout<<"Task 3: listened to "<< i << " song. \n";
}
};

int main() {

std::thread my_thread_1(playGame, 2);
std::thread my_thread_2(&Dinner::cook, Dinner(), "lasagna", 3);
std::thread my_thread_3(music, 3);

my_thread_1.join();
my_thread_2.join();
my_thread_3.join();

printf("swap back to main");

return 0;
}

Note: the 2. callable — function object, like it’s name, it need parameter like the following:

std::thread my_thread_2(
&Dinner::cook, //class's function
Dinner(), //class object
"lasagna", 3 //parameter of the function
);

The output of the program is differ by your OS. You could get this:

Task 2: dinner lasagna is baked for 0hour. 
Task 2: dinner lasagna is baked for 1hour.
Task 2: dinner lasagna is baked for 2hour.
Task 3: listened to 0 song.
Task 3: listened to 1 song.
Task 3: listened to 2 song.
Task 1: played 0 hour.
Task 1: played 1 hour.
swap back to main

or this:

Task 3: listened to 0 song. 
Task 1: played Task 2: dinner lasagna is baked for 0hour.
Task 2: dinner lasagna is baked for 0Task 3: listened to 1 hour.
1 song.
Task 3: listened to 2 song.
hour.
Task 2: dinner lasagna is baked for 2hour.
Task 1: played 1 hour.
swap back to main

or any other…

--

--

chuuuing
chuuuing

No responses yet