为什么控制台应用程序在使用包含使用互斥锁的静态变量的共享 dll 时挂起?

Why console app hangs when using a shared dll that containg static variable that use mutex?

我有一个包含 class 的共享 dll 库,如下所示:

里面A.dll >> 头文件:

class API ErrorHandler  
{
public:
    ErrorHandler();

    virtual ~ErrorHandler();
protected:  
    static ErrorHandler* defaultHandler();

private:
    static ErrorHandler* _pHandler;
    static std::mutex     _mutex;
};

来源(.cpp)

ErrorHandler* ErrorHandler::_pHandler = ErrorHandler::defaultHandler();
std::mutex ErrorHandler::_mutex;


ErrorHandler::ErrorHandler()
{
}


ErrorHandler::~ErrorHandler()
{
}

ErrorHandler* ErrorHandler::defaultHandler()
{   
    static SingletonHolder<ErrorHandler> sh;
    return sh.get(); **<<====== here we get hanged** see the declaration of get
}

SingletoneHolder头文件

template <class S>
class SingletonHolder
{
public:
    SingletonHolder():
        _pS(0)
    {
    }

    ~SingletonHolder()
    {
        delete _pS;
    }

    S* get()
    {
        std::lock_guard<std::mutex> lock(_m); <===== cause thread hang
        if (!_pS) _pS = new S;

        return _pS;
    }

private:
    S* _pS;
    std::mutex _m;
};

构建以上代码后(所有与编译器设置相关的东西都正确配置)现在我想在我的控制台应用程序中使用它。

在 运行 控制台应用程序之后,应用程序挂起并且永远不会到达主要功能。

为什么 std::lock_guard<std::mutex> lock(_m); 挂起并阻止主线程继续执行?

什么是备选方案?

我正在使用 VS2013 Update5.

主文件内容:

#include "ErrorHandler" <== when remove this include app run correctly
#include <iostream>

int main()
{
   getchar();
   return 0;
}

首先,您应该 post main 的确切内容 - 空 main 一切正常。当 ErrorHandler class 在 main 中实例化时,事情就变糟了。

其次,静态成员的初始化发生在 __DllMainCRTStartup 内部,正如我标记为重复的 SO 问题中所述,MSDN 指出使用来自 __DllMainCRTStartup 的同步原语会导致死锁。一种可能的解决方案是切换到临界区。