0

Ich habe eine DLL-Bibliothek geteilt, die wie unten eine Klasse enthält:Warum hängt die Konsolenanwendung bei der Verwendung einer DLL mit statischen Variablen, die Mutex verwenden, nicht auf?

innerhalb A.dll >>Header-Datei:

class API ErrorHandler 
{ 
public: 
    ErrorHandler(); 

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

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

Quelle (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 Header-Datei

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; 
}; 

Nachdem ich den obigen Code erstellt habe (alles was mit der Compilereinstellung zu tun hat), möchte ich ihn jetzt in meiner Konsolen App verwenden.

Nach dem Ausführen der Konsolen-App hängt die App und erreicht nie die Hauptfunktion.

Warum std::lock_guard<std::mutex> lock(_m); hängt und verhindern, dass Hauptthread weiter ausgeführt wird?

Was ist eine Alternative?

Ich verwende VS2013 Update5.

Inhalt der Hauptdatei:

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

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

Funktioniert für mich auf VS 2013 Update 5 mit einem leeren 'main'. Sie sollten den Inhalt der Konsolenanwendung posten, möglicherweise rufen Sie einige der exportierten Klassenmitglieder auf. –

+0

Mögliches Duplikat von [C++ 11 std :: mutex in Visual Studio 2012 Deadlock, wenn von DllMain() gesperrt] (http://stackoverflow.com/questions/14711263/c11-stdmutex-in-visual-studio-2012- deadlock-when-locked-from-dllmain) –

+0

Zwei Mutex-Objekte, ich rieche eine Ratte. Veröffentlichen Sie den Aufruf-Stack des Deadlock-Threads. –

Antwort

1

Zunächst sollen Sie genauen Inhalt der main Post - mit einem leeren main allem funktioniert. Die Dinge gehen nach Süden, wenn die ErrorHandler Klasse in main instanziiert wird. Die Initialisierung Ihrer statischen Member tritt innerhalb von __DllMainCRTStartup auf. Und wie in der SO-Frage, die ich als doppelt gekennzeichnet habe, angegeben, gibt MSDN an, dass die Verwendung von Synchronisierungsprimitiven aus __DllMainCRTStartup einen Deadlock verursachen kann. Eine mögliche Lösung besteht darin, zu einem kritischen Bereich zu wechseln.

+0

zuallererst, meine Hauptfunktion ist emty und ich schließe nur die ErrorHandler-Klasse-Header-Datei. (Wenn ich EventHandler-Header-Datei von Include-Liste entfernen, funktioniert alles gut und ich kann Pause innerhalb der Hauptfunktion bekommen). Ich implementiere die Mutext-Klasse mit Critical_Section und jetzt funktioniert alles gut – amir110

+0

@ amir110 Entschuldigung, wenn meine Formulierung falsch war - ich meine, Sie müssen die 'ErrorHandler'-Instanz irgendwo instanziiert haben, ok vielleicht nicht innerhalb' main' aber irgendwo, sonst wenn du hattest keine anrufe an die dll, die nicht einmal geladen würden. –

+0

als ErrorHandler-Klassenvariable, die als statisch deklariert ist (wenn Sie den obigen Code überprüfen), wird sie instanziiert, wenn die App aktiv wird. – amir110