C++ 11 feature: C++ Multithreading Tutorial: Recursive mutex in C++ threading

In the previous chapter we learn about timed_mutex, in this chapter we shall learn about recursive_mutex.

Need for recursive mutex?

Suppose there is a recursive function that acquires lock before calling itself as shown below:

recursive_function()
{
	.
	.
	.
	m.lock();

	recursive_function();

	m.unlock();

}

Now the thread T1 will enter the function and locks itself. Again, it will recursively call the function, and tries to acquire the lock. But it has already acquired the lock previously, it will wait for that lock to get unlocked. This will result in a dead lock situation.

To solve this, we have recursive mutex.

Recursive Mutex:

When you lock using recursive mutex, it will first check if the mutex is locked. If the mutex is locked by the same thread that is asking for the lock, then it will allow to lock multiple times.

Now again, the number of times you lock the mutex, the same number of times unlock should be called. But in our example, we have written unlock after the recursive call.

Hence if we use normal mutex, it will unlock only once. But if you use recursive mutex, then it will call unlock for exact number of times it has locked.

Recursive mutex will work for recursion and also for looping cases.

Recursive mutex is a class in C++ available in STD library.

std::recursive_mutex;

Member Functions include:

lock();
try_lock();
unlock();

Now we shall understand recursive_mutex with help of an example.:

Example 1: recursive_mutex for recursion:

#include <iostream>       // std::cout
#include <chrono>         // std::chrono::milliseconds
#include <thread>         // std::thread
#include <mutex>          // std::timed_mutex

// for more tutorials visit www.ProDeveloperTutorial.com

using namespace std;

std::recursive_mutex mtx;

int count_num = 0;

// thread_num will give the name of thread.
// val will give number of times to loop.

void recursion_fun (int thread_num, int val) 
{
    if(val < 0) // base case to end recursion
        return;

    mtx.lock();

    cout<<"Thread "<<thread_num<<" count = "<<count_num++<<endl;

    recursion_fun(thread_num, --val);

    mtx.unlock();

}

int main ()
{
    std::thread t1 (recursion_fun, 1, 5);
    std::thread t2 (recursion_fun, 2, 6);
    
    t1.join();
    t2.join();
    

  return 0;
}

Output:

Thread 2 count = 0
Thread 2 count = 1
Thread 2 count = 2
Thread 2 count = 3
Thread 2 count = 4
Thread 2 count = 5
Thread 2 count = 6
Thread 1 count = 7
Thread 1 count = 8
Thread 1 count = 9
Thread 1 count = 10
Thread 1 count = 11
Thread 1 count = 12
Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *