Mutex stands for Mutual Exclusion. In C++, std::mutex class is a synchronization primitive that is used to protect the shared data from being accessed by multiple threads simultaneously. The shared data can be in the form of variables, data structures, etc.
std::mutex class implements mutex in C++. It is defined inside <mutex> header file.
Need for Mutex in C++
In C++, when multiple threads modify the same shared resources simultaneously may cause race conditions. It may produce unpredictable output or unexpected behavior while executing the program. Mutex is used to avoid race conditions by locking the current thread so that all the other threads cannot access the shared resources at that time and unlocking it when the current thread is done.
Syntax for Mutex in C++
The use of mutex can be divided into three steps:
1. Create a std::mutex Object
std::mutex mutex_object_name;
2. Lock the Thread
The lock() function of the std::mutex class locks the thread and allows only the current thread to run until it is unlocked. It prevents the shared resource from being accessed by multiple threads simultaneously.
mutex_object_name.lock()
3. Unlock the thread
The unlock() of the std::mutex function is used to release the lock after execution of the code piece containing the possibility of race condition occurrence. It resumes all the waiting threads.
mutex_object_name.unlock()
Working of Mutex in C++Example of Mutex in C++
Let's create a shared integer variable, which can be accessed globally inside the program. Create a function to increment the number by 1 for 1000000 times using a for loop. Create two threads named thread1 and thread2 to run the same increment() function.
In this case, thread1 will increment the number by 1 for 1000000 times and thread2 will increment the number by 1 for 1000000 times. So the expected output is 2000000.
However, there is a possibility of occurrences of race conditions when multiple threads try to modify the same resource simultaneously. So the value of the number cannot be predicted.
Code Without Mutex Synchronization
C++
// C++ program to illustrate the race conditions
#include <iostream>
#include <thread>
using namespace std;
// Shared resource
int number = 0;
// function to increment the number
void increment(){
// increment number by 1 for 1000000 times
for(int i=0; i<1000000; i++){
number++;
}
}
int main()
{
// Create thread t1 to perform increment()
thread t1(increment);
// Create thread t2 to perform increment()
thread t2(increment);
// Start both threads simultaneously
t1.join();
t2.join();
// Print the number after the execution of both threads
cout << "Number after execution of t1 and t2 is " << number;
return 0;
}
Output
The same program is executed three times to observe the behavior when modifying shared resources without thread synchronization.
Run 1:
Number after execution of t1 and t2 is 1058072
Without Mutex Output 1
Run 2:
Number after execution of t1 and t2 is 1456656
Without Mutex Output 2
Run 3:
Number after execution of t1 and t2 is 2000000
Without Mutex Output 3
Explanation
It is clearly visible that the output of the program is unpredictable. When two threads are running at the same time causes race cases that create unpredictable output. There is no guarantee that the output to be 2000000. This unpredictable behavior is happening because of the concurrent modification of the same shared variable simultaneously using multiple threads.
Code with Mutex Synchronization
C++
// C++ program to illustrate the thread synchronization using mutex
#include <iostream>
#include <thread>
using namespace std;
// import mutex from C++ standard library
#include <mutex>
// Create object for mutex
mutex mtx;
// Shared resource
int number = 0;
// function to increment the number
void increment(){
// Lock the thread using lock
mtx.lock();
// increment number by 1 for 1000000 times
for(int i=0; i<1000000; i++){
number++;
}
// Release the lock using unlock()
mtx.unlock();
}
int main()
{
// Create thread t1 to perform increment()
thread t1(increment);
// Create thread t2 to perform increment()
thread t2(increment);
// Start both threads simultaneously
t1.join();
t2.join();
// Print the number after the execution of both threads
std::cout<<"Number after execution of t1 and t2 is "<<number;
return 0;
}
Output
The same program is executed three times to observe the behavior when modifying shared resource with thread synchronization using mutex.
Run 1:
Number after execution of t1 and t2 is 2000000
Mutex Output 1
Run 2:
Number after execution of t1 and t2 is 2000000
Mutex Output 2
Run 3:
Number after execution of t1 and t2 is 2000000
Mutex Output 3
Explanation
Here, the output is stable. The threads are synchronous. Mutex object pauses all other thread than current thread using lock(). Now, only it allows one thread (current thread) at a time until it is unlocked using unlock() function.
Similar Reads
std::shared_mutex in C++
In C++, std::mutex is a mechanism that locks access to the shared resource when some other thread is working on it so that errors such as race conditions can be avoided and threads can be synchronized. But in some cases, several threads need to read the data from shared resources at the same time. H
4 min read
Multithreading in C++
Multithreading is a technique where a program is divided into smaller units of execution called threads. Each thread runs independently but shares resources like memory, allowing tasks to be performed simultaneously. This helps improve performance by utilizing multiple CPU cores efficiently. Multith
6 min read
system() in C/C++
The system() function is used to invoke an operating system command from a C/C++ program. For example, we can call system("dir") on Windows and system("ls") in a Unix-like environment to list the contents of a directory. It is a standard library function defined in <stdlib.h> header in C and
6 min read
Namespace in C++
Name conflicts in C++ happen when different parts of a program use the same name for variables, functions, or classes, causing confusion for the compiler. To avoid this, C++ introduce namespace. Namespace is a feature that provides a way to group related identifiers such as variables, functions, and
7 min read
std::promise in C++
In C++ multithreading, a thread is the basic unit that can be executed within a process and to communicate two or more threads with each other, std::promise in conjunction with std::future can be used. In this article, we will discuss the std::promise in C++ and how to use it in our program. What is
3 min read
Thread Pool in C++
The Thread Pool in C++ is used to manage and efficiently resort to a group (or pool) of threads. Instead of creating threads again and again for each task and then later destroying them, what a thread pool does is it maintains a set of pre-created threads now these threads can be reused again to do
6 min read
Jump statements in C++
Jump statements are used to manipulate the flow of the program if some conditions are met. It is used to terminate or continue the loop inside a program or to stop the execution of a function. In C++, there is four jump statement: Table of Content continue Statementbreak Statementreturn Statementgot
4 min read
Pause Command in C++
pause() is a C++ method used to pause a program during execution. It allows the user to input or read data. The pause approach makes the system more readable and user-friendly by allowing the user to read the instructions before performing any task. What is pause()?The pause() function is used to pa
3 min read
Stack in C++ STL
In C++, stack container follows LIFO (Last In First Out) order of insertion and deletion. It means that most recently inserted element is removed first and the first inserted element will be removed last. This is done by inserting and deleting elements at only one end of the stack which is generally
5 min read
Infinite Loop in C++
In C++, a loop is a part of code that is executed repetitively till the given condition is satisfied. An infinite loop is a loop that runs indefinitely, without any condition to exit the loop. In this article, we will learn about infinite loops in C++, its types and causes and what are its applicati
6 min read