使用场景:一个类的不同成员函数之间,存在相互调用的情况, 如果这样的成员函数作为线程的入口函数时,就会出现在成员函数 func1()中对某个互斥量上锁,并且, func1()中调用了成员函数 func2() ,实际上 func2()为了保护成员数据,func2()内部也对同一个互斥量上锁。 在我们对 std::mutex 的使用经验中, 这样的情况,必定会导致未定义的行为,从而导致死锁的产生。
C++标准库为此提供了 std::recursive_mutex 互斥量, 它在具备 std::mutex 的功能之上, 还可以可以支持上面描述的 “对同一个互斥量进行嵌套上锁” 的能力。
注意:这个 “嵌套锁”的能力只是在同一线程中, 多个线程间还是保持与 std::mutex 一致的互斥同步能力。
下面分别贴出成员函数存在嵌套调用时 std::recursive_mutex 比 std::mutex 超强的表现能力。
1 #include
2 #include
3 #include
4 #include
5
6 class Try_Recursive_Mutex
7 {
8 std::mutex mtx;
9 std::recursive_mutex recur_mtx;
10 std::chrono::milliseconds sleep_time = std::chrono::milliseconds(1000);
11 public:
12 Try_Recursive_Mutex();
13
14 void fun1(){
15 std::lock_guard lkgd( recur_mtx );
16 std::cout<"---thread id: "<"---"<<std::endl;
17 std::this_thread::sleep_for(sleep_time);
18 fun2();
19 }
20
21 void fun2(){
22 std::lock_guard lkgd( recur_mtx );
23 std::cout<"---thread id: "<"---"<<std::endl;
24 std::this_thread::sleep_for(sleep_time);
25 fun3();
26 }
27
28 void fun3(){
29 std::lock_guard lkgd( recur_mtx );
30 std::cout<"---thread id: "<"---"<<std::endl;
31 std::this_thread::sleep_for(sleep_time);
32 }
33 };
1 #include "Try_Recursive_Mutex.h"
2 #include
3
4 int main()
5 {
6 Try_Recursive_Mutex trm;
7 std::thread th_1(&Try_Recursive_Mutex::fun1, &trm);
8 std::thread th_2(&Try_Recursive_Mutex::fun1, &trm);
9 std::thread th_3(&Try_Recursive_Mutex::fun1, &trm);
10 th_1.join();
11 th_2.join();
12 th_3.join();
13 return 0;
14 }
运行结果如下:
16:24:34: Starting D:\a_zhm\StudyCode\threadStudy\14_protect_unNormalUpdate_data\build-protect_unNormalUpdate_data-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug\debug\protect_unNormalUpdate_data.exe…
Try_Recursive_Mutex::fun1—thread id: 13484—
Try_Recursive_Mutex::fun2—thread id: 13484—
Try_Recursive_Mutex::fun3—thread id: 13484—
Try_Recursive_Mutex::fun1—thread id: 8224—
Try_Recursive_Mutex::fun2—thread id: 8224—
Try_Recursive_Mutex::fun3—thread id: 8224—
Try_Recursive_Mutex::fun1—thread id: 528—
Try_Recursive_Mutex::fun2—thread id: 528—
Try_Recursive_Mutex::fun3—thread id: 528—
16:24:43: D:/a_zhm/StudyCode/threadStudy/14_protect_unNormalUpdate_data/build-protect_unNormalUpdate_data-Desktop_Qt_5_9_8_MSVC2015_64bit-Debug/debug/protect_unNormalUpdate_data.exe exited with code 0
同样的情况,我们使用传统的 std::mutex 来实现,就会出现未定义行为,产生死锁而导致程序崩溃:
1 #include
2 #include
3 #include
4 #include
5
6 class Try_Recursive_Mutex
7 {
8 std::mutex mtx;
9 std::recursive_mutex recur_mtx;
10 std::chrono::milliseconds sleep_time = std::chrono::milliseconds(1000);
11 public:
12 Try_Recursive_Mutex();
13
14 void fun1(){
15 std::lock_guard lkgd( mtx );
16 std::cout<"---thread id: "<"---"<<std::endl;
17 std::this_thread::sleep_for(sleep_time);
18 fun2();
19 }
20
21 void fun2(){
22 std::lock_guard lkgd( mtx );
23 std::cout<"---thread id: "<"---"<<std::endl;
24 std::this_thread::sleep_for(sleep_time);
25 fun3();
26 }
27
28 void fun3(){
29 std::lock_guard lkgd( mtx );
30 std::cout<"---thread id: "<"---"<<std::endl;
31 std::this_thread::sleep_for(sleep_time);
32 }
33 };
程序的运行情况如下:
总结: 新科技 std::recursive_mutex 就是好用!!! 特定场合,我们就选用特殊的技术。
Original: https://www.cnblogs.com/azbane/p/15814093.html
Author: 我是张洪铭我是熊博士
Title: C++ std::Recursive_mutex 支持 “对同一互斥量进行嵌套加锁”
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535286/
转载文章受原作者版权保护。转载请注明原作者出处!