When to use a recursive mutex?

I understand that a recursive mutex allows you to lock a mutex more than once without going to a dead end, and it needs to be unlocked as many times. But in what specific situations do you need to use a recursive mutex? I am looking for situations at the code / code level.

+44
c ++ multithreading mutex recursion recursive-mutex
Mar 10 '10 at 7:01
source share
5 answers

For example, if you have a function that calls it recursively, and you want to get synchronized access to it:

void foo() { ... mutex_acquire(); ... foo(); ... mutex_release(); } 

without a recursive mutex, you first need to create an entry point function, and this becomes cumbersome if you have a set of functions that are mutually recursive. Without a recursive mutex:

 void foo_entry() { mutex_acquire(); foo(); mutex_release(); } void foo() { ... foo(); ... } 
+37
Mar 10 '10 at 7:03
source share

Recursive and non-recursive mutexes have various use cases . No type of mutex can easily replace another. Non-recursive mutexes have less overhead, and recursive mutexes are useful or even necessary for semantics in some situations, and dangerous or even broken semantics in other situations. In most cases, someone can replace any strategy using recursive mutexes with another safer and more efficient strategy based on using non-recursive mutexes.

  • If you just want to exclude other threads from your mutex-protected resource, you can use any type of mutex , but you may want to use a non-recursive mutex because of its lower overhead.
  • If you want to call functions that block the same mutex recursively, then they either
    • must use one recursive mutex or
    • you need to unlock and block the same non-recursive mutexes again and again (beware of parallel threads!) (assuming it sounds semantically, it could be a performance problem) or
    • must somehow annotate which mutexes they have already blocked (simulating recursive ownership / mutexes).
  • If you want to block several objects protected by a mutex from a set of such objects where sets could be created by merging, you can choose
    • for use on one object exactly one mutex , which allows more threads to work in parallel or
    • use one link for each object for any possibly recursive mutex to reduce the likelihood of not locking all mutexes or
    • use one comparable link for one object for any possibly shared non-recursive mutex , bypassing the intention to block several times.
  • If you want to release a lock in another thread, except that it was locked, you need to use non-recursive locks (or recursive locks that explicitly allow this, rather than throwing exceptions).
  • If you want to use synchronization variables, then you need to be able to explicitly unlock the mutex , waiting for any synchronization variable so that the resource is allowed to be used in other threads. This is only possible with non-recursive mutexes , since recursive mutexes can already be locked by the calling function of the current function.
+19
Apr 2 2018-11-11T00:
source share

If you want to see sample code that uses recursive mutexes, look at the sources for Electric Fence for Linux / Unix. "Twas is one of the common Unix tools for finding" bounds "on overspending and overwriting read / write, as well as using freed memory before Valgrind .

Just compile and connect the electric fence with sources (the -g option with gcc / g ++), and then bind it to your software using the link option to the liberator and start navigating through calls to malloc / free. http://elinux.org/Electric_Fence

+3
Apr 27 '12 at 15:44
source share

Today I came across the need for a recursive mutex, and, in my opinion, this is the simplest example among the published answers: This is a class that provides two API functions: Process (...) and reset ().

 public void Process(...) { acquire_mutex(mMutex); // Heavy processing ... reset(); ... release_mutex(mMutex); } public void reset() { acquire_mutex(mMutex); // Reset ... release_mutex(mMutex); } 

Both functions should not be launched at the same time, because they change the interiors of the class, so I wanted to use a mutex. The problem is that process () calls reset () internally and this will create a dead end because mMutex is already received. Instead, locking with a recursive lock fixes the problem.

+2
May 08 '15 at 17:16
source share

This would be a problem if the thread blocked an attempt to get (again) an existing mutex ...

Is there a reason why a mutex cannot be simultaneously received by the same thread?

+1
Mar 10 '10 at 7:08
source share



All Articles