How to Use the std::mutex Synchronization Primitive in C++
Last Updated :
28 May, 2024
In multi-threaded programming, it is essential to ensure that shared resources are accessed in a controlled and synchronized manner to maintain data consistency and prevent race conditions. The std::mutex synchronization primitive was introduced in C++ 11 to allow threads to acquire exclusive ownership of a shared resource for a period of time, ensuring thread-safe access. In this article, we will learn how to use the std::mutex synchronization primitive in C++.
std::mutex Synchronization Primitive in C++
Before using the std::mutex synchronization primitive, we must understand how it works. A std::mutex (short for mutual exclusion) is a lock object that allows only one thread to access a shared resource at a time. When a thread needs to access a shared resource, it attempts to acquire the mutex lock. If the lock is available, then the thread acquires it and proceeds to access the shared resource. If the lock is currently held by another thread, the requesting thread will be blocked until the lock is released. Following is the syntax to use the std::mutex in C++:
Syntax
To understand the syntax of std::mutex in C++, we must know how to declare the mutex object, how to acquire a lock on mutex, and how to unlock it.
Declaring the mutex object
std::mutex mtx_name;
where:
- mtx_name is the name of the mutex object.
- You can declare multiple mutex objects in a single program as well.
Locking the mutex
mtx_name.lock()
The lock() function is used to acquire the lock on the mutex object. If the mutex is already locked by another thread, then the calling thread is blocked until the mutex is free.
Unlocking the mutex
mtx_name.unlock()
The unlock() function releases the lock on the mutex object. It is essential to unlock the mutex when the thread has completed it's job so that the shared resource can be made available for the other threads as well.
C++ Program to use std::mutex Synchronization Primitive
The following program illustrates how std::mutex synchronization primitive can be used in C++:
C++
// C++ Program to use std::mutex Synchronization Primitive
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
// Global mutex object to synchronize access to shared_data
mutex mtx;
// Shared data to be incremented by multiple threads
int shared_data = 0;
// Function to increment shared_data within a loop
void increment_data() {
for (int i = 0; i < 1000000; ++i) {
// Acquire the lock to access shared_data
mtx.lock();
// Increment shared_data
++shared_data;
// Release the lock after updating shared_data
mtx.unlock();
}
}
// Main function
int main() {
// Create two threads to concurrently increment shared_data
thread thread1(increment_data);
thread thread2(increment_data);
// Wait for both threads to finish execution
thread1.join();
thread2.join();
// Output the final value of shared_data after both threads finish
cout << "Final value of shared_data: " << shared_data << endl;
return 0;
}
Output
Final value of shared_data: 2000000
Time Complexity: O(N), where N is the number of iterations.
Auxiliary Space: O(1)
Explanation
In the above example , we have two threads that called the increment_data function concurrently, which increments the shared_data variable one million times. The std::mutex object mtx ensures that only one thread can access the shared_data variable at a time and also ensures no race condition occurs during the execution of the program.
Similar Reads
How to Use the Volatile Keyword in C++? In C++, the volatile keyword is used to tell the compiler that the value of the variable declared using volatile may change at any time. In this article, we will learn how to use the volatile keyword in C++. Volatile Keyword in C++We can use the volatile keyword for different purposes like declaring
2 min read
How to Implement User Defined Shared Pointers in C++? shared_ptr is one of the smart pointer introduced as a wrapper to the old raw pointers in C++ to help in avoiding the risks and errors of raw pointers. In this article, we will learn how to implement our own user defined shared pointer in C++. What is shared_ptr in C++? A std::shared_ptr is a contai
5 min read
How to Implement User Defined Shared Pointers in C++? shared_ptr is one of the smart pointer introduced as a wrapper to the old raw pointers in C++ to help in avoiding the risks and errors of raw pointers. In this article, we will learn how to implement our own user defined shared pointer in C++. What is shared_ptr in C++? A std::shared_ptr is a contai
5 min read
How to wake up a std::thread while it is sleeping? In this article, we will discuss how to wake up a std::thread while it is sleeping. It is known that a thread can't be exited when it is sleeping. So it is woken up using a command as: std::condition_variable Below is the pseudo-code to implement the same:Â C++ // Custom Class struct MyClass { // Co
3 min read
How to Iterate a STL Queue in C++? A Queue is a linear structure that follows a particular order in which the operations are performed. The order is First In First Out (FIFO). Syntax: queue<datatype> queuename;Datatype: Queue can take any data type depending on the values, e.g. int, char, float, etc. The std: :queue container d
4 min read
How to Join a Thread in C++? In C++, a thread is a basic element of multithreading that represents the smallest sequence of instructions that can be executed independently by the CPU. In this article, we will discuss how to join a thread in C++. How to Join a Thread in C++?Joining a thread is a means to wait for the thread to c
2 min read