gpt4 book ai didi

c++11 - 使用 std::mutex 而不是 boost::mutex 时出现未处理的异常

转载 作者:行者123 更新时间:2023-12-03 06:22:45 27 4
gpt4 key购买 nike

我尝试摆脱代码中的一些 boost 依赖项,转而使用新的 C++11 功能 (Visual Studio 2013)。

在我的一个组件中,我使用了 boost::mutexboost::lock_guard<boost::mutex> 一起一切都很好。当我使用std::mutex时与 std::lock_guard<std::mutex> 一起相反,从 main() 返回时出现以下错误.

Unhandled exception at 0x7721E3BE (ntdll.dll) in GrabberTester.exe: 0xC0000005: Access violation reading location 0xA6A6B491.

真实的项目非常复杂,因此很难提供完整的工作代码示例来重现这个问题。在我的真实项目中,互斥体在运行时加载的共享库中使用(但在我从 main() 返回时应该已经卸载)。

我的问题是:

  • boost::mutexstd::mutex设计的行为完全相同?
  • 如果不是,有什么区别?使用std::mutex时需要注意什么?而不是boost::mutex
  • 在共享库中,我使用 boost::thread 创建线程框架。难道是std::mutex只能与 std::thread 一起使用s 并且与 boost::thread 不兼容是吗?

编辑:

我注意到的另一件事:当我卸载动态加载的共享库时,这需要一些时间。 (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

最佳答案

问题很可能是静态初始化 hell ,我最近经历了几乎同样的事情。这是正在发生的事情:

  1. 您有一个静态互斥体(可能是静态类的成员)。
  2. doexit() 代码开始清理静态内容。
  3. 互斥体在 doexit() 的某个地方被销毁
  4. 某些东西在被销毁后会使用互斥锁,通常是在析构函数中。

问题是您并不真正知道静态对象的销毁顺序。所以如果你有:

static std::mutex staticMutex;

void someFunction()
{
std::unique_lock<std::mutex> lock(staticMutex);
doSomethingAwesome();
}

...

StaticObjA::~StaticObjA()
{
someFunction();
}

那么当调用 ~StaticObjA() 时,您的静态互斥体可能已经被删除/销毁/deadbeef。当对象定义在不同的编译单元中(即定义在不同的文件中)时,问题会更加严重。

我的解决建议是尝试减少对静态对象的依赖,您可以尝试使用 1 个静态对象来负责其他所有内容的构造/销毁,以便您可以控制事件的顺序。或者根本不使用静态。

关于c++11 - 使用 std::mutex 而不是 boost::mutex 时出现未处理的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27800412/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com