Ich versuche, einige der Boost-Abhängigkeiten in meinem Code loszuwerden und stattdessen die neuen C ++ 11-Funktionen (Visual Studio 2013) zu verwenden.
In einer meiner Komponenten habe ich boost::mutex
zusammen mit boost::lock_guard<boost::mutex>
benutzt und alles hat gut funktioniert. Wenn ich stattdessen std::mutex
zusammen mit std::lock_guard<std::mutex>
verwende, erhalte ich den folgenden Fehler, wenn ich von main()
zurückkomme.
Nicht behandelte Ausnahme bei 0x7721E3BE (ntdll.dll) in GrabberTester.exe: 0xC0000005: Zugriff auf Leseort 0xA6A6B491 der Zugriffsverletzung.
Das eigentliche Projekt ist ziemlich komplex und es ist daher schwierig, ein vollständiges funktionierendes Codebeispiel zur Verfügung zu stellen, um dieses Problem zu reproduzieren. In meinem realen Projekt werden die Mutexe in einer gemeinsam genutzten Bibliothek verwendet, die zur Laufzeit geladen wird (die aber bereits entladen sein sollte, wenn ich von main()
zurückkomme).
Meine Fragen sind:
boost::mutex
und std::mutex
so konzipiert, dass sie sich absolut gleich verhalten? std::mutex
anstelle von boost::mutex
? boost::thread
Framework. Könnte es sein, dass std::mutex
nur mit std::thread
s verwendet werden kann und nicht mit boost::thread
s? Eine Sache, die mir aufgefallen ist: Wenn ich die dynamisch geladene shared library entlade, braucht es etwas Zeit. (Die DLL greift auf die Hardware zu und es dauert einige Zeit, bis alles sauber heruntergefahren ist). Wenn ich zu std::mutex
wechsle, sieht es jedoch so aus, als könnte die DLL fast sofort entladen werden, aber das Programm stürzt dann ab, wenn es von main()
zurückkehrt. Ich habe den Eindruck, dass das Problem mit std::mutex
speziell im Kontext einer DLL liegt.
Sowohl die Anwendung als auch die DLL sind in der Debug-Konfiguration mit dem Toolset v120 frisch erstellt und statisch mit der Laufzeitbibliothek (/ MTd) verknüpft.
Unten finden Sie den Callstack. Die Ausnahme scheint von irgendwo im Treiber zu kommen. Nur zufällig habe ich herausgefunden, dass es damit zu tun hat, welche Implementierung von Mutex ich benutze.
%Vor% Vielleicht ist das ein Fehler im OpenNI2 SDK, der nur unter diesen sehr speziellen Bedingungen beobachtet werden kann. Also habe ich das Openni-Tag zu dieser Frage hinzugefügt. Dennoch bleibt die Frage: Warum funktioniert es mit boost::mutex
, aber nicht mit std::mutex
?
Das Problem ist wahrscheinlich statische Init-Hölle, ich habe vor kurzem fast dasselbe durchgemacht. Hier ist, was geht:
Das Problem ist, dass Sie die Reihenfolge der Zerstörung für statische Objekte nicht wirklich kennen. Also wenn du hast:
%Vor%....
%Vor%Dann kann Ihr statischer Mutex bereits gelöscht / zerstört / deadbeef sein, wenn ~ StaticObjA () aufgerufen wird. Das Problem wird verschlimmert, wenn die Objekte in verschiedenen Kompilierungseinheiten definiert sind (d. H. In verschiedenen Dateien definiert sind).
Meine Empfehlung zum Lösen ist, zu versuchen, die Abhängigkeit von statischen Objekten zu reduzieren. Sie könnten versuchen, ein statisches Objekt zu haben, das sich um die Konstruktion / Zerstörung von allem anderen kümmert, so dass Sie die Reihenfolge der Ereignisse steuern können. Oder verwende einfach keine Statik.
Ich füge das gleiche Problem hinzu und was gelöst ist ... eine vollständige manuelle Reinigung + Neuerstellung! Überprüfen Sie das Löschen aller .obj-, .dll-, .lib-Dateien.
Benutze nicht std :: mutex (oder recursive_mutex, ...) von Mircosoft !!!! Ich hatte ähnliche Probleme. Ich verwende VS2012.
Wenn Sie std :: mutex in einer DLL verwenden, dürfen Sie diese DLL nicht entladen. Weil Sie ein undefiniertes Verhalten erhalten. (in meinem Fall 0xC0000005: Leseort für Zugriffsverletzung ....). Oder Sie können die DLL nicht entladen. ("? Runtime?" erhöht den Ladezähler. Double FreeLibrary () entlädt die DLL)
Ich hatte ein ähnliches Problem, als mein Code versuchte, zweimal den gleichen Mutex zu sperren: Eine Funktion erlangte die Sperre und rief dann eine andere Funktion auf, die versuchte, eine Sperre für den gleichen globalen / statischen Mutex zu erhalten.
%Vor%Tags und Links c++11 mutex openni unhandled-exception boost-mutex