一例MSVC2013中recursive_mutex引起崩溃的原因分析

本文分析了CUI程序中DLL的全局对象在析构过程中调用recursive_mutex::lock()函数导致的崩溃问题。原因是当通过Ctrl+C触发DLL释放时,系统创建的远程线程未能正确初始化,进而引发recursive_mutex::lock()函数崩溃。

复现方法:CUI程序,DLL中的全局对象在析构时调用recursive_mutex::lock()函数,运行时通过Ctrl+C触发。


原因分析:DLL被释放时,会自动析构所有的全局对象。由于Ctrl+C的实现为系统创建一个远程线程调用dllmain并析构全局对象,而这个远程线程缺少一些必要的初始化过程,造成recursive_mutex::lock()函数崩溃。


以下是分析时的截图:


### 关于 `std` 命名空间缺少 `recursive_mutex` 成员的错误分析 当遇到编译器提示“命名空间 `std` 中不存在 `recursive_mutex` 成员”的错误时,通常有以下几个可能的原因: #### 1. **未启用 C++11 或更高版本标准** 如果使用的编译器默认支持的是旧版 C++ 标准(如 C++98),而 `std::recursive_mutex` 是自 C++11 起引入的功能,则需要显式指定使用 C++11 或更新的标准[^2]。 解决方案是在编译命令中加入 `-std=c++11` 参数(对于 GCC 和 Clang 编译器)或者 `/std:c++17`(针对 MSVC 编译器)。例如: ```bash g++ -std=c++11 your_program.cpp -o your_program ``` #### 2. **编译器不支持 C++11 的 `<mutex>` 头文件** 部分老旧编译器可能尚未实现完整的 C++11 功能集。如果确认已启用了 C++11 支持但仍报错,可能是由于所用编译器过老所致。建议升级至最新稳定版本的编译器以获得更好的兼容性和功能支持[^3]。 #### 3. **拼写错误或遗漏头文件** 确保正确包含了必要的头文件 `<mutex>` 并且没有拼写错误。如果没有包含该头文件或将类名称误写作其他形式(如大小写敏感问题),也会引发类似的错误消息。 正确代码应如下所示: ```cpp #include <iostream> #include <thread> #include <mutex> std::recursive_mutex mymutex; void test() { std::lock_guard<std::recursive_mutex> myguard(mymutex); mymutex.lock(); std::cout << "1" << std::endl; mymutex.unlock(); mymutex.lock(); mymutex.unlock(); } int main() { std::thread a(test), a2(test); a.join(); a2.join(); } ``` #### 4. **平台特定限制** 某些嵌入式系统或其他特殊环境下的工具链可能裁剪掉了部分 STL 组件,包括多线程相关的功能。在这种情况下,即使语法完全正确也可能无法通过编译。需查阅目标平台文档了解其具体支持情况并考虑替代方案[^4]。 --- ### 示例修正后的完整代码片段 以下是基于上述讨论调整过的完整示例程序,确保能够成功运行的前提条件均已满足: ```cpp #include <iostream> #include <thread> #include <mutex> // 使用 std::recursive_mutex 实现递归锁 std::recursive_mutex mymutex; void test() { // 自动管理锁生命周期的对象 lock_guard std::lock_guard<std::recursive_mutex> myguard(mymutex); // 显示调用 lock/unlock 方法演示手动控制过程 mymutex.lock(); std::cout << "Thread ID: " << std::this_thread::get_id() << ", Output: 1\n"; mymutex.unlock(); // 再次尝试获取同一把锁 (在同一线程内有效) mymutex.lock(); std::cout << "Thread ID: " << std::this_thread::get_id() << ", Output: 2\n"; mymutex.unlock(); } int main() { // 创建两个并发执行的任务实例 std::thread t1(test); std::thread t2(test); // 等待子线程完成工作后再退出主线程 t1.join(); t2.join(); return 0; } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值