【发布时间】:2015-03-04 05:21:49
【问题描述】:
我尝试摆脱代码中的一些 boost 依赖项,转而使用新的 C++11 功能 (Visual Studio 2013)。
在我的一个组件中,我使用了boost::mutex 和boost::lock_guard<boost::mutex>,一切正常。当我将std::mutex 与std::lock_guard<std::mutex> 一起使用时,从main() 返回时出现以下错误。
GrabberTester.exe 中 0x7721E3BE (ntdll.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0xA6A6B491。
实际项目相当复杂,因此很难提供完整的工作代码示例来重现此问题。在我的实际项目中,互斥锁用于在运行时加载的共享库中(但在我从main() 返回时应该已经卸载了)。
我的问题是:
-
boost::mutex和std::mutex的设计行为是否完全相同? - 如果不是,有什么区别?使用
std::mutex而不是boost::mutex时需要注意什么? - 在共享库中,我使用
boost::thread框架创建线程。难道std::mutex只能和std::threads一起使用,和boost::threads不兼容?
编辑:
我注意到的另一件事:当我卸载动态加载的共享库时,这需要一些时间。 (DLL 访问硬件,需要一些时间才能完全关闭所有内容)。当我切换到std::mutex 时,看起来 DLL 几乎可以立即卸载,但是当从main() 返回时程序会崩溃。我的印象是std::mutex 的问题特别是在 DLL 的上下文中。
编辑 2:
应用程序和 DLL 都是使用 v120 工具集在调试配置中全新构建的,并与运行时库 (/MTd) 静态链接。
编辑 3:
您可以在下面找到调用堆栈。异常似乎来自驱动程序的某个地方。只是偶然我发现它与我使用的互斥锁实现有关。
ntdll.dll!7721e3be()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7721e023()
kernel32.dll!76b014ad()
msvcr100.dll!71b0016a()
PS1080.dll!oniDriverDestroy() Line 29
OpenNI2.dll!oni::implementation::DeviceDriver::~DeviceDriver() Line 95
OpenNI2.dll!oni::implementation::Context::shutdown() Line 324
OpenNi2Grabber.dll!openni::OpenNI::shutdown() Line 2108
OpenNi2Grabber.dll!GrabberSingletonImpl::~GrabberSingletonImpl() Line 46
OpenNi2Grabber.dll!`GrabberSingletonImpl::getInstance'::`2'::`dynamic atexit destructor for 'inst''()
OpenNi2Grabber.dll!doexit(int code, int quick, int retcaller) Line 628
OpenNi2Grabber.dll!_cexit() Line 448
OpenNi2Grabber.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 169
OpenNi2Grabber.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 399
OpenNi2Grabber.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 340
ntdll.dll!7722b990()
ntdll.dll!77249bad()
ntdll.dll!77249a4f()
kernel32.dll!76b079ed()
GrabberTester.exe!__crtExitProcess(int status) Line 776
GrabberTester.exe!doexit(int code, int quick, int retcaller) Line 678
GrabberTester.exe!exit(int code) Line 417
GrabberTester.exe!__tmainCRTStartup() Line 264
GrabberTester.exe!mainCRTStartup() Line 165
kernel32.dll!76b0338a()
ntdll.dll!7722bf32()
ntdll.dll!7722bf05()
编辑 4:
也许这是 OpenNI2 SDK 中的一个错误,只有在这些非常特殊的条件下才能观察到。所以我在这个问题中添加了 openni 标签。但问题仍然存在:为什么它适用于 boost::mutex 而不适用于 std::mutex?
【问题讨论】:
-
就我而言,stl 和 boost 实现之间没有显着差异。我见过互斥锁这样做的唯一原因是当一个线程锁定而另一个尝试解锁时。我会确保我对所有可能的实例都使用 lock_guards,并通过大量同步调试输出调查所有其他用途。
-
我知道标准线程工具的一些 VS2013 实现在各个方面都存在缺陷。不知道
mutex是否是其中的一部分。 -
你有没有机会以某种方式混合不同的运行时版本?
-
或者没有进行完整的重建? (即一些目标文件、DLL 和其他仍在使用旧代码的东西)
-
至少发布崩溃的堆栈跟踪。
标签: c++11 mutex openni unhandled-exception boost-mutex