Multithreading in C++
Multithreading in C++ is a programming technique that allows a program to execute multiple threads concurrently. Threads are lightweight processes that share the same memory space and can perform tasks independently, enhancing the program's efficiency and responsiveness. C++ provides libraries, like std::thread, for creating and managing threads. Multithreading is particularly useful for tasks that can be parallelized, such as handling multiple user requests or improving performance in multi-core processors.
Syntax
std::thread is the thread class that represents a single thread in C++. To start a thread we simply need to create a new thread object and pass the executing code to be called (i.e, a callable object) into the constructor of the object.
Defining the Callable
In C++, a callable is a function or object that can be executed by a thread. It can be a function pointer, a lambda expression, or an object with the operator() overloaded, defining its behavior when invoked.
1. Function Pointer
A function pointer is a variable that holds the memory address of a function. It can be used as a callable for creating threads in C++. When defining a thread using a function pointer, you pass the pointer to the function along with any required parameters.
2. A Function Object (Functor)
A function object, or functor, is a user-defined class or struct that overloads the operator(). Functors can be used as callable objects for creating threads. When creating a thread with a function object, you pass an instance of the object, and the operator() is executed in the new thread.
3. A Lambda Expression
Lambda expressions provide a concise way to define anonymous functions in C++. They can capture variables from their enclosing scope and are often used as callable objects for creating threads. When launching a thread with a lambda, you pass the lambda itself to the std::thread constructor.
4. Non-Static Member Function
Non-static member functions are part of a class and require an instance of the class to be called. They can be used as callables for creating threads in C++. To launch a thread using a non-static member function, you pass both the member function's pointer and an instance of the class to the std::thread constructor.
5. Static Member Function
Static member functions are associated with a class but do not require an instance of the class to be called. They can be used as callable objects for creating threads. When launching a thread with a static member function, you only need to pass the pointer to the static member function along with any required parameters to the std::thread constructor.
Creating Threads
A thread can be created using the pthread_create function.
The following syntax is used to create a thread:
Syntax:
Example:
Output:
Parameters & Descriptions
Parameter | Description |
---|---|
thread | it is a unique identifier for the new thread. |
attr | is an attribute object used to set the thread attributes. It can be NULL or set to default values. |
start_routine | Leads to thread execution once it is created. |
arg | It is passed as a single argument to start_routine. |
Terminating Threads
To terminate a thread, pthread_exit() function is used.
Usually, the pthread_exit() function is called after the completion of work by the thread.
Syntax:
Example
After compilation,
Output:
Passing Arguments to Threads in C++
Multiple arguments can be passed using the s structure in a thread. Any data type can be passed in a thread callback since it points to void.
Let's understand more clearly with the help of an example.
Output:
Joinable and Not Joinable Threads
Threads are joined using the join() function. Join() is a member function of the thread class that returns a value when all the threads terminate. The main thread waits for the child thread to finish its execution.
Not Joinable thread: A thread is said to be not joinable after the join() function returns a value
Joinable thread: A thread is said to be joinable if a thread represents a thread of execution that hasn't joined.
We can check if a thread is joinable by using the joinable() function. Joinable() returns true if the thread is joinable and false otherwise.
Syntax:
Joining and Detaching Threads
Whether a thread is detached or joined is determined the moment a thread gets created.
A joinable thread can be joined and the thread that can never be joined is said to be detached thread.
The following two routines are used to determine Joining and Detachable threads.
Conclusion
- Multithreading is used for the parallel execution of multiple tasks.
- It increases the efficiency of the program.
- We create an object of std::thread to create a thread while doing multithreading in C++.
- A callable is defined in three ways: By using a pointer to an object, By using Lamda expression and by using a function object.
- thread.h header file is used to provide functionality to multithreading in C++ programs.