【问题标题】:Cannot lock a c++ 11 std::mutex on a DLL [duplicate]无法在 DLL 上锁定 c++ 11 std::mutex [重复]
【发布时间】:2014-07-07 00:08:23
【问题描述】:

我试图通过使用 std::lock 对象来防止对 DLL 初始化函数的多次调用。

在独立程序上使用这样的程序时:

#include <mutex>
std::mutex mtx;

void main(){
  mtx.lock();
  (...)
  mtx.unlock()
}

当在 DLL 上调用时,此完全相同的代码无法通过 mtx.lock()

BOOL APIENTRY DllMain(HANDLE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved)
{
    f_Init(VERSION_ID);
    return TRUE;
}

//On another cpp file, a static library actually.
#include <mutex>
std::mutex mutex_state;
void f_Init(DWORD version){
    //Acquire the state lock
    mutex_state.lock(); //<-- Will NOT get past this line
    (...)
    mutex_state.unlock();
}

为什么在这种情况下无法锁定互斥锁?

我目前使用的是 Microsoft Visual Studio 2013。

【问题讨论】:

  • 是的,几乎是同一个问题。此外,如果 D Schwartz(下)是正确的,则不需要 DLLMAIN 上的锁定。
  • 作为参考,Microsoft Connect bug report 按设计关闭。
  • 你的实际初始化包括什么?很可能是在DllMain 中不应该做的事情。 (请参阅 this article 了解为什么 DllMain 应该最小。)

标签: c++ c++11 visual-studio-2013 mutex


【解决方案1】:

不需要互斥锁。对DllMain 的访问由实现序列化。

系统在整个进程范围内对入口点的访问进行序列化。 DllMain 中的线程持有加载程序锁,因此不能动态加载或初始化其他 DLL。 -- DllMain Entry Point

当您输入DllMain 时,您的代码会出现死锁,因为您已经持有锁。在持有一些未知的锁组合的同时尝试获取额外的锁是非常非常有可能死锁的。您应该永远DllMain 中获取任何额外的锁。

例如,考虑是否需要附加一些额外的 DLL 来锁定互斥锁。不能同时附加两个 DLL,并且正在附加您的 DLL。第一次锁定互斥体可能需要分配内存,而分配内存可能需要附加 DLL——所以不要在 DllMain 中这样做。

顺便说一句,这些痛苦的限制同样适用于全局对象的构造函数和析构函数。

【讨论】:

    猜你喜欢
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多