1. What is a multithread
Multithreading allows our computer to run two or more programs concurrently.
Multithreading is different from multiprogram.
2. How the c++ language and OS support the multithread
C++ does not contain built-in support for multithreaded applications until C++11. It relies entirely upon POSIX which is provided by OS.
The std::thread is implemented on top of pthreads in an environment supporting pthreads. The std::thread library includes many abstract features.
3. A bad example
The problem of the following code is that the main thread create a thread t1, and the main thread does not wait for t1 thread termination. It continues its work. The main thread finishes execution, but t1 is still running. So a run time error happens. All the threads must be terminated before the main thread is terminated.
#include
#include
using namespace std;
void threadFunc(){
cout << "Thread Func" << endl;
}
int main(){
thread t1(threadFunc);
return 0;
}
so we need the following code:
int main(){
thread t1(threadFunc);
t1.join(); // main thread is blocked until t1 is not finished
return 0;
}
4. Look at some APIs of threads
std::thread join
void join(); Blocks the current thread until the thread identified by *this finishes its execution.
who is the current thread? The main thread.
who is the "identified by *this" ? The thread t1
5. Creating threads using library thread from C++11( the following code is from https://en.cppreference.com/w/cpp/thread/thread/thread)
Command to compile the following code in my computer is $ g++ -std=c++17 hello.cpp -lpthread
#include
#include
#include
#include
void f1(int n){
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 1 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void f2(int& n){
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 2 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
class foo{
public:
void bar(){
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 3 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
class baz{
public:
void operator()(){
for (int i = 0; i < 5; ++i) {
std::cout << "Thread 4 executing\n";
++n;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
int n = 0;
};
int main(){
int n = 0;
foo f;
baz b;
std::thread t1; // t1 is not a thread of execution
std::thread t2(f1, n + 1); // pass by value
std::thread t3(f2, std::ref(n)); // pass by reference
std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
// t5 runs foo::bar() on object f, we need the function ref, and the object ref.
std::thread t5(&foo::bar, &f);
// t6 runs baz::operator() on object b, we need a object and its operator()
std::thread t6(b);
t2.join();
t4.join();
t5.join();
t6.join();
std::cout << "Final value of n is " << n << '\n';
std::cout << "Final value of foo::n is " << f.n << '\n';
}
6. Creating a thread using POSIX
The API of pthread : https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html
A good source talking about the pthread: https://www.cs.cmu.edu/afs/cs/academic/class/15492-f07/www/pthreads.html