Test environment: Ubuntu 18.04.3 LTS g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0.
Can std::mutex be reentrant? Why does the following test code 1 pass?
code1:
#include <iostream>
#include <mutex>
std::mutex g_mtx4val;
int g_val = 5;
void test() {
std::lock_guard<std::mutex> lck(g_mtx4val);
std::cout << "g_val=" << g_val << std::endl;
if (g_val > 0) {
--g_val;
test();
}
}
int main() {
test();
std::cout << "done ...." << std::endl;
return 0;
}
peanut@peanut:~/demo$ g++ test.cpp
peanut@peanut:~/demo$ ./a.out
g_val=5
g_val=4
g_val=3
g_val=2
g_val=1
g_val=0
done ...
code2:
// Same code 1
int main() {
std::thread t1(test);
t1.join();
std::cout << "done ...." << std::endl;
return 0;
}
peanut@peanut:~/demo$ g++ test2.cpp -lpthread
peanut@peanut:~/demo$ ./a.out
g_val=5
^C
peanut@peanut:~/demo$
code2 has a deadlock. Why code1 can pass the test?
From the documentation page:
mutex offers exclusive, non-recursive ownership semantics
So the answer to the question in the title is no.
Can std::mutex be reentrant?
No, but if you want a recursive mutex, the std::recursive_mutex class provides that functionality.
Why does the following test code 1 pass?
What behavior were you expecting to see? The std::mutex documentation page simply says:
A calling thread must not own the mutex prior to calling lock or try_lock.
... it doesn't say what will happen if the calling thread breaks the above rule; which means that a program that breaks the rule may "appear to work", but even so is still incorrect and buggy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With