Today, I spent time reading about multithreading in C++.
Using multiple threads is a great way to increase performance as they can be used to run different processes at the same time. The main() function is using the main thread and we can initialize threads there. We can tell the main thread to wait for a process to complete before moving on using the thread.join() or keep going without waiting with thread.detach().
My notes from my study:
The thread library was first introduced
In every application, there is a default thread which is used by the main() function. The threads header contains a class that represents individual threads of execution. A thread of execution is a sequence of instructions that can be executed concurrently with other such sequences in multithreading environments while sharing the same address space.
An initialized thread is an active thread. An active thread is joinable and holds a unique ID. A joinable thread becomes not joinable if moved from, or if their join or detach are called on them.
Examples of threading
A browser might use threads to handle tabs
Visual Studio code editor might be using threading for auto-completion
There are 5 ways to create threads:
Function Pointers
Lambda Functions
Functors
Member Functions
Static Member Functions
Multithreading makes the execution of the code faster. This is a great way to create high-performing software.
Let's create a thread for a with a function pointer:
std::thread t1(functionName, arg1, arg2);
Now our thread is created and it can run the function. We also need to use the thread.join() function to bring the results back to the original thread. This is needed because the results have to go back to the main thread to use them.
t1.join();
The join() function will make the program wait until the processes in the created threads end. Multithreading has multiple use cases.
Note
If we create multiple threads at the same time it doesn't guarantee which one will start first.
Join(), Attach(), and Joinable
#include <iostream>
#inclide <thread>
void run(int count)
{
while(count-- > 0)
{
cout << count << endl;
}
}
int main()
{
std::thread t1(run, 10);
if (t1.joinable())
{
t1.join();
}
return 0;
}
With join(), our main thread waits for the other thread to complete. It is a good practice to use the joinable() function to check if the created thread is joinable.
Always use the joinable() function before joining threads.
if (t1.joinable())
{
t1.join();
}
The detach() function is used to detach the newly created thread from the main thread. Its usage is quite simple.
c1.detach();
The detached thread will run a process independently which means that the program might end before the process completes. If that happens, then the thread will not achieve anything and the function's process won't complete.
Use std::this_thread:: functions for more threading options.
// Make the thread wait for 5 seconds
std::this_thread::sleep_for(chrono::seconds(5));
Note
Always use join() or detach() as it should be called for every thread. Failing to do so will lead to a crash.
Special Thanks
#cpp #multithreading #performance