PDFVersion
No ads? No problem! Download the PDF book of this tutorial for just $24.99. Your support will help us reach more readers.
Thank You!
WHAT IS MULTI-THREADING?
Multi-threading, or multitasking, refers to managing multiple tasks simultaneously. It involves handling more than one task at a given point in time, also known as multi-processing.
It's no secret that for many jobs multitasking is an essential requirement. A common example of multitasking at work is a representative juggling numerous tasks at once like talking on the telephone, taking notes and checking emails at the same time. we all have multitasking for each minute like we talk on the phone while driving, text while keeping conversation with friends, and constantly check emails while watching favorite shows etc.
A programmable approach to achieve multi-tasking in known as multi-threading. A multi-threaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution.
The concept of multi-threading stems from multitasking, which enables systems to execute multiple programs concurrently. There are two types of multitasking: process-based and thread-based. Process-based multitasking involves running multiple programs concurrently, while thread-based multitasking involves executing fragments of the same program simultaneously.
In a multi-threaded program, different parts can execute concurrently, with each part known as a thread. Threads enhance flexibility and efficiency, although C++ itself does not directly support multi-threading; it relies on the operating system or virtual machines.
Threads are a popular way to enhance application performance through parallelism. For example, in a browser, multiple tabs can function as different threads. MS Word utilizes multiple threads for tasks like text formatting and processing inputs. Threads outperform processes due to faster thread creation, context switching, termination, and communication.
- Thread creation is significantly quicker.
- Context switching between threads is more efficient.
- Threads can be terminated with ease.
- Communication between threads is faster.
Before creating threads in C++, it's essential to include the <thread>
library. Here's an example demonstrating multi-threading in C++:
#include <iostream>
#include <thread>
using namespace std;
void function() {
cout << "Hello world: " << endl;
}
int main() {
thread call_function(function);
return 0;
}
For multi-threading, the Built-in support was first introduced in C++11. But in order to create multi-threaded C++ programs we have to include the Header file <thread>
.
In the above example, we create a thread object named call_function()
with the parameter function
When we compile this program, a runtime error occurs because the main thread does not wait for the call_function()
thread to terminate. The main thread finishes its execution while call_function()
is still running, causing an error. It is essential to ensure that all threads are terminated before the main thread finishes execution.
To avoid runtime errors, it's necessary to ensure that the main thread waits for child threads to complete execution. This can be achieved by joining the threads. The join()
function ensures that the main thread waits for the child thread to finish execution before continuing.
Threads are joined using the join()
member function of the thread class. After joining, the main thread will wait until the child thread completes its execution.
Let's revisit the previous example and join the threads to ensure proper execution.
#include <iostream>
#include <thread>
using namespace std;
void function() {
cout << "Hello world: " << endl;
}
int main() {
thread call_function(function);
call_function.join();
return 0;
}
In the above example, our program will execute successfully. However, after join()
returns, the threads will no longer be joinable. Therefore, it is advisable to check if a thread is joinable using the joinable()
member function of the thread class.
if(call_function.joinable()) {
call_function.join();
}
else
cout<<" Call_function is unable to join. "<< endl;
If a thread's execution has not yet been joined, it is joinable. However, if the thread is default constructed, moved, assigned to another thread, or if the join()
or detach()
member function is called, it will no longer be joinable.
The detach()
member function of the thread class is used to separate a thread from its parent thread.
In our previous examples, we used functions and objects without passing any arguments. However, we can also initialize a thread using a function with parameters. Let's look at an example to see how this is done.
#include <iostream>
#include <thread> //required for threads operation:
#include <chrono> //required for time operation (sleep);
using namespace std;
void functionA(int thread_number, int iterations, long delay) {
int loop = 0;
// Loop a specified number of iterations
while(loop < iterations) {
// Sleep for a specified time
this_thread::sleep_for(chrono::milliseconds(delay));
cout << "Thread " << thread_number << " Reporting: " << loop
<< " with delay " << delay << endl;
loop++;
}
}
int main() {
thread thread1(functionA, 1, 10, 1555);
thread thread2(functionA, 2, 10, 2222);
char result;
cout << "Press a key to finish" << endl;
cin >> result;
// Join the two worker threads with the main thread
thread1.join();
thread2.join();
return 0;
}
Multi-threading offers advantages such as:
- Utilizes multiple processors for simultaneous execution, enhancing performance.
- Offers benefits even on a uni-processor system.
- Mitigates the impact of slow operations like accessing the hard disk by allowing other threads to continue execution.
- Ensures efficient resource utilization by enabling other threads to proceed when one thread stalls.
Sardar Omar
I did my hardest to present you with all of the information you need on this subject in a simple and understandable manner. However, if you have any difficulties understanding this concept or have any questions, please do not hesitate to ask. I'll try my best to meet your requirements.