well, recursive_mutex
is for... recursive function!
In some Operating systems, locking the same mutex twice can lead to a system error( in which, the lock may be released copmletely, application may crash and actually all kind of weird and undefined behaviour may occur).
look at this (silly example)
void recursivePusher(int x){
if (x>10){
return;
}
std::lock_guard<std::mutex> lock(m);
queue.push(x);
recursivePusher(x+1);
}
this function recursivly increments x
and pushes it into some shared queue
.
as we talked above - the same lock may not be locked twice by the same thread, but we do need to make sure the shared queue isn't baing altered by mutilple threads.
one easy solution is to move the lociking outside the recursive function, but what happens if we can't do it? what happens if the function called is the only one that can lock the shared resource?
for example, my calling function may look like this:
switch(option){
case case1: recursivly_manipulate_shared_array(); break;
case case2: recursivly_manipulate_shared_queue(); break;
case case3: recursivly_manipulate_shared_map(); break;
}
ofcourse, you wouldn't lock all three(shred_Array,shared_map,shared_queue) only for one of them will be altered.
the solution is to use std::shared_mutex
:
void recursivePusher(int x){
if (x>10){
return;
}
std::lock_guard<std::recursive_mutex> lock(m);
queue.push(x);
recursivePusher(x+1);
}
if the same thread don't need to lock the mutex recursivly it should use regular std::mutex
, like in your example.
PS. in your snippet, empty
is not the same as T::empty
.
calling data.empty()
doesn't call empty
recursivley.