Lock innerhalb von mutex::unlock() ?
-
Ich habe hier ein Problem mit einem Thread, der nicht zum Ende kommt.
gdb sagt mir, der Thread hängt in:#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007ffff6d495b0 in pthread_cond_broadcast@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S:136
#2 0x00007ffff752ed59 in std::condition_variable::notify_all() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x0000000000410014 in std::shared_timed_mutex::unlock (this=0x7fffffffd608) at /usr/include/c++/4.9/shared_mutex:159
#4 0x00000000004109c6 in std::unique_lockstd::shared\_timed_mutex::unlock (this=0x7fffeb5fdde0) at /usr/include/c++/4.9/mutex:530
#5 0x000000000040f2ed in MyClass::tick (this=0x7fffffffd5f0, timedelta=0,050000000000000003) at MyClass.cpp:48wobei die Zeilen 47/48 in MyClass.cpp lauten:
assert(excllock.owns_lock()); excllock.unlock();und excllock ist vom Typ std::unique_lockstd::shared\_timed_mutex.
Wie kann das überhaupt sein, dass der Thread innerhalb eines Aufrufs von unlock hängen bleibt?

-
Wie du siehst, gibt es keine Antworten auf deinen Beitrag. Das ist kein Zufall, sondern liegt an deinem Beitrag.
Wie man Probleme nachstellbar und nachvollziehbar macht
-
OK, dann so:
Gibt es irgendwelche denkbaren Umstände, unter denen ein Aufruf von std::unique_lockstd::shared\_timed_mutex::unlock() blockieren könnte?
-
wx++ schrieb:
Gibt es irgendwelche denkbaren Umstände, unter denen ein Aufruf von std::unique_lockstd::shared\_timed_mutex::unlock() blockieren könnte?
Offensichtlicherweise das Szenario in deinem Code. Wieso also uns raten lassen, wenn deine Frage doch eigentlich ist, was an deinem Code falsch ist, nicht was was falsch sein könnte?
-
wx++ schrieb:
OK, dann so:
Gibt es irgendwelche denkbaren Umstände, unter denen ein Aufruf von std::unique_lockstd::shared\_timed_mutex::unlock() blockieren könnte?Ein denkbarer Umstand wäre, dass der aktuelle Thread nicht das Lock auf den Mutex hält, dann wäre das
unlock()meines Wissens undefined behavior. Das solltest du aber eigentlich durch deine Assertion ausgeschlossen haben. Ist es vielleicht möglich, dass du nur ein Shared-Lock auf den Mutex hältst?unlock()ist soweit ich weiss nur für exklusive Locks (bin mir nicht sicher, aber ich denke auch dann hätte die Assertion fehlschlagen müssen).Generell hat SeppJ recht. Mehr kann man nur mit mehr Kontext sagen. Allerdings muss ich zugeben, dass ich das auch etwas seltsam finde, dass ausgerechnet das
unlock()blockiert. Der Callstack legt ausserdem nahe, dass er blockiert, während er versucht eine interne Condition Variable zu benachrichtigen. Auch wenn man wegen der wenigen Infos nicht viel sagen kann, sagt mir mein Bauchgefühl, dass du eventuell auf einen libstdc++-Bug gestossen sein könntest. Immerhin ist dershared_timed_mutexsoweit ich weiss noch ein relativ neues Feature.Lässt sich der Deadlock eigentlich zuverlässig reproduzieren? Optimal wäre natürlich ein möglichst kurzes Testprogramm bei dem dieser Fehler auftritt. Dann lässt sich leichter sagen, ob es ein Standardbibliothek-Bug ist, oder ob du selbst etwas komisches machst. Eine weitere Möglichkeit wäre auch, den Mutex durch eine andere Implementierung zu ersetzen. Soweit ich weiss, unterstützt der z.b. der
boost::shared_mutexdie selbe Funktionalität.Finnegan
-
Vermutlich hast du die
shared_timed_mutexschon zerstört bevor du versuchst sie zu unlocken.
(Oder die Implementierung dershared_timed_mutexist wirklich fehlerhaft - aber ich gehe erstmal immer von nem eigenen Fehler aus, also auch wenn ich meine eigenen Programme debugge.)
-
Vermutlich hast du die shared_timed_mutex schon zerstört bevor du versuchst sie zu unlocken.
Das ist eine gute Idee, der ich nachgehen werde.
Ansonsten habe ich noch diese Antwort gefunden, signal handlers sind in meinem Fall aber nicht involviert: http://stackoverflow.com/questions/4345315/pthread-cond-signal-deadlocks .
-
BTW: Wenn der Verdacht zutrifft, dann sollte man vermutlich dem Library-Dev-Team den Vorschlag schicken ein
assert(!locked())in den dtor einzubauen.
-
Anscheinend hatte hustbaer den richtigen Riecher. Ein anderer Thread hat die Struktur zu der der mutex gehört u.U. schon dealloziert während der "fehlerhafte" Thread noch lief.
Das Problem ist nur sporadisch aufgetreten, aber ich konnte es jetzt auch in einer größeren Anzahl Tests nicht mehr reproduzieren und nehme daher an, dass damit die Ursache gefunden ist.
-
wx++ schrieb:
Anscheinend hatte hustbaer den richtigen Riecher. Ein anderer Thread hat die Struktur zu der der mutex gehört u.U. schon dealloziert während der "fehlerhafte" Thread noch lief.
Jo, das klingt nach einem äußerst "denkbaren Umstand"

BTW... falls du sowas ähnliches nicht eh schon machst, ich habe speziell bei solchen Sachen wie mit deiner Struktur immerstd::shared_ptrals sehr nützlich empfunden.Finnegan
-
Gar kein Riecher.
Ich hab' einfach nur__lll_lock_waitgegoogelt und dann diesen Fred hier gefunden (3. Treffer mit Google!):http://stackoverflow.com/questions/8248458/pthread-cond-signal-causing-deadlock
Nachdem das exakt das selbe Problem ist wie du in deinem Callstack hast (
pthread_cond_broadcasthängt obwohl es niemals hängen dürfte)...