C++ std::Recursive_mutex 支持 “对同一互斥量进行嵌套加锁”

使用场景:一个类的不同成员函数之间,存在相互调用的情况, 如果这样的成员函数作为线程的入口函数时,就会出现在成员函数 func1()中对某个互斥量上锁,并且, func1()中调用了成员函数 func2() ,实际上 func2()为了保护成员数据,func2()内部也对同一个互斥量上锁。 在我们对 std::mutex 的使用经验中, 这样的情况,必定会导致未定义的行为,从而导致死锁的产生。

 

C++标准库为此提供了 std::recursive_mutex 互斥量, 它在具备 std::mutex 的功能之上, 还可以可以支持上面描述的  “对同一个互斥量进行嵌套上锁” 的能力。

注意:这个 “嵌套锁”的能力只是在同一线程中, 多个线程间还是保持与 std::mutex 一致的互斥同步能力。

下面分别贴出成员函数存在嵌套调用时 std::recursive_mutex 比 std::mutex 超强的表现能力。

 1 #include <thread>
 2 #include <iostream>
 3 #include <mutex>
 4 #include <chrono>
 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<std::recursive_mutex> lkgd( recur_mtx );
16         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
17         std::this_thread::sleep_for(sleep_time);
18         fun2();
19     }
20 
21     void fun2(){
22         std::lock_guard<std::recursive_mutex> lkgd( recur_mtx );
23         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
24         std::this_thread::sleep_for(sleep_time);
25         fun3();
26     }
27 
28     void fun3(){
29         std::lock_guard<std::recursive_mutex> lkgd( recur_mtx );
30         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
31         std::this_thread::sleep_for(sleep_time);
32     }
33 };

 

 1 #include "Try_Recursive_Mutex.h"
 2 #include <QApplication>
 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_zhmStudyCodethreadStudy14_protect_unNormalUpdate_databuild-protect_unNormalUpdate_data-Desktop_Qt_5_9_8_MSVC2015_64bit-Debugdebugprotect_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 <thread>
 2 #include <iostream>
 3 #include <mutex>
 4 #include <chrono>
 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<std::mutex> lkgd( mtx );
16         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
17         std::this_thread::sleep_for(sleep_time);
18         fun2();
19     }
20 
21     void fun2(){
22         std::lock_guard<std::mutex> lkgd( mtx );
23         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
24         std::this_thread::sleep_for(sleep_time);
25         fun3();
26     }
27 
28     void fun3(){
29         std::lock_guard<std::mutex> lkgd( mtx );
30         std::cout<<__FUNCTION__<<"---thread id: "<<std::this_thread::get_id()<<"---"<<std::endl;
31         std::this_thread::sleep_for(sleep_time);
32     }
33 };

 

程序的运行情况如下:

C++ std::Recursive_mutex 支持 “对同一互斥量进行嵌套加锁”

 

 

 

总结: 新科技 std::recursive_mutex 就是好用!!! 特定场合,我们就选用特殊的技术。

 

原文链接: https://www.cnblogs.com/azbane/p/15814093.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ std::Recursive_mutex 支持 “对同一互斥量进行嵌套加锁”

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/398238

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月12日 上午9:34
下一篇 2023年4月12日 上午9:35

相关推荐