Threadsicherheit und Deadlocks
-
Hallo.
Ich begebe mich das erste Mal richtig auf das Gebiet des Multithreadings und ich habe ein Programm das aus einem Workerthread besteht, der unter anderem ein GUI aktualisiert das in einem anderen Thread läuft sowie von diesem GUI Kommandos signaldriven über Variablenwerte erhält.
Ich benutze um das Ganze abzusichern boost::mutex und dazu boost::mutex::scoped_lock.Aber es passiert regelmäßig dass das GUI sich aufhängt.
Ich mache dafür mal einen Deadlock verantwortlich. Aber soetwas kann doch gar nicht passieren, wenn der Workerthread nicht in einer Schleife bleibt, oder?Grüße,
Flo
-
Icematix schrieb:
Aber es passiert regelmäßig dass das GUI sich aufhängt.
Ich mache dafür mal einen Deadlock verantwortlich. Aber soetwas kann doch gar nicht passieren, wenn der Workerthread nicht in einer Schleife bleibt, oder?Doch, kann es. Deadlocks haben nix mit schleifen zu tun:
Gegeben: Thread A, Thread B, Mutex X, Mutex Y.
Folgender Programmablauf: Thread A lockt Mutex X, Thread B lockt Mutex Y, Thread B will Mutex X locken, Thread A will Mutex Y locken ====> Deadlock, A wartet auf Y, B wartet auf X. Ohne Schleife
-
Stimmt, daran habe ich noch nicht Gedacht
Was kann man dagegen (außer sich nochmal Gedanken über die Programmstruktur zu machen, was ich sowieso tun werde) dagegen tun?
Softwaretechnisch versteht sich.Dann werde ich mal als temporären Fix 1 Mutex für alles verwenden. Dann warten die Threads zwar relativ lange, aber die Zugriffe auf den geteilten Speicher sind nicht gerade häufig.
Grüße,
FloEdit: Ok, mit 1 Mutex macht das Programm überhaupt nichts mehr, absolut tot. Komisch.
-
Da sollte man halt gut überlegen, vor man mit Threads um sich schmeist. Was anderes hilft da nicht.
Passend zu deiner Signatur müsste dein Programm sich jetzt selbst garbage collecten.
-
Icematix schrieb:
Stimmt, daran habe ich noch nicht Gedacht
Was kann man dagegen (außer sich nochmal Gedanken über die Programmstruktur zu machen, was ich sowieso tun werde) dagegen tun?
Softwaretechnisch versteht sich.Dann werde ich mal als temporären Fix 1 Mutex für alles verwenden. Dann warten die Threads zwar relativ lange, aber die Zugriffe auf den geteilten Speicher sind nicht gerade häufig.
Grüße,
FloEdit: Ok, mit 1 Mutex macht das Programm überhaupt nichts mehr, absolut tot. Komisch.
Da gibts verschiedene Mittel. Eine recht simple Strategie: die Threads muessen die Mutexe immer in der gleichen Reihenfolge anfordern.
D.h., wenn ein Thread Mutex X und Mutex Y benoetigen, muss immer X vor Y angefordert werden.
-
Icematix schrieb:
das GUI
EPIC FAIL
-
ROFL schrieb:
Icematix schrieb:
das GUI
EPIC FAIL
_Das_ grafische Userinterface...
-
die grafische benutzerschnittstelle.
-
GUIs sind was für n00bs. wer brauch die???
-
Blue-Tiger, danke für die hilfreiche Antwort.
Ich habe deinen Rat befolgt und trotzdem bleibt der Thread des GUI im Lock hängen.Ich werde etwas weiter dran rätseln, komm gerade darauf echt nicht klar
Zumindest konnte ich Code, der den Fehler verursacht stark eingrenzen. Ich poste ihn mal, ich erwarte nicht dass irgendjemand meinen Mist debugged, aber ich tue es mal vlt ist ja jemandem langweilig und er würde ihn kurz überfliegenWorker-Thread, Auszug: http://pastebin.com/m505fa3fa
GUI-Thread, Auszug: http://pastebin.com/m3a6538a4Da sollte man halt gut überlegen, vor man mit Threads um sich schmeist. Was anderes hilft da nicht.
Passend zu deiner Signatur müsste dein Programm sich jetzt selbst garbage collecten.
Nun ja, Multithreading ist hier nicht zum Spaß sondern Pflicht, da einige Calls blockieren.
Außerdem sage ich noch dazu dass ich im Bereich der Koordinierung mehrerer Threads unerfahren bin. Ich verstehe deinen Flamepost nicht.
Wenn ich genau wüsste was zu tun wäre, würde ich hier nicht posten. Logische Sache? Denke ja.ROFL schrieb:
Icematix schrieb:
das GUI
EPIC FAIL
Wenn ich blöde Kommentare von 13-Jährigen hören will, lasse ich dich das wissen.
-
Icematix schrieb:
Worker-Thread, Auszug: http://pastebin.com/m505fa3fa
du hast hier zwei 'scoped' locks in einer 'while(true)'. scoped-lock hört sich für mich so an, dass der unlock erst nach dem verlassen des scopes erfolgt. also mach noch irgendwo 'nen scope hin '{}', benutz manuelle locks, oder lagere den code, der gelockt sein soll, in funktionen aus (damit so'n scoped-lock auch beendet wird). grundsätzlich gilt ja sowieso, dass locks so früh wie möglich wieder freigegeben werden sollen. dein code sieht so aus, als hätteste dir darüber überhaupt keine gedanken gemacht *fg*
-
;fricky schrieb:
Icematix schrieb:
Worker-Thread, Auszug: http://pastebin.com/m505fa3fa
du hast hier zwei 'scoped' locks in einer 'while(true)'. scoped-lock hört sich für mich so an, dass der unlock erst nach dem verlassen des scopes erfolgt. also mach noch irgendwo 'nen scope hin '{}', benutz manuelle locks, oder lagere den code, der gelockt sein soll, in funktionen aus (damit so'n scoped-lock auch beendet wird). grundsätzlich gilt ja sowieso, dass locks so früh wie möglich wieder freigegeben werden sollen. dein code sieht so aus, als hätteste dir darüber überhaupt keine gedanken gemacht *fg*
try grenzt doch einen Scope ein.
Und naja, in dem Codesnippet kann ich die Locks nicht früher frei machen.
-
Icematix schrieb:
try grenzt doch einen Scope ein.
ok. aber wahrscheinlich kannste die deadlock-wahrscheinlichkeit erhöhen, wenn du den sleep kürzer machst *fg*. dann verdächtige ich mal den logMutex, schmeiss aus der 'printWaypointLog' mal den mutex raus, oder, falls es ohne mutex abstürzen kann, kommentier alles innerhalb der funktion aus. und wenn das nix hilft, dann klink dich mit 'nem debugger ein, wenn's hängt und schau dir den zustand der mutexe an, um den übeltäter zu finden.
dann sehe ich da noch was furchtbares: http://aszt.inf.elte.hu/~gsd/klagenfurt/material/ch03s06.html
The simple mutex can be locked only ones. If the same thread try to lock such a mutex twice, it deadlocks.
^^voll doof, was soll sowas? oder benutzt du einen 'recursive mutex'? da du sowieso unter windows programmierst, nimm besser das: http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx
When a thread owns a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution.
^^windows CriticalSections sind vermutlich auch in der ausführung wesentlich schneller.
-
Icematix schrieb:
Worker-Thread, Auszug: http://pastebin.com/m505fa3fa
GUI-Thread, Auszug: http://pastebin.com/m3a6538a4der halbe code besteht ja aus mutex... Eigentlich wollte ich ja sagen, ein paar "printf" und du weißt wo es hängt, aber bei dem Code würde ich sagen, überleg dir genau wo du locken musst und wie du die stellen ganz kurz hältst und schreib es neu. und mach keine zwei lock in einer funktion, ohne das erste wieder frei zu geben. das schreit ja nach deadlock.
Icematix schrieb:
Ich verstehe deinen Flamepost nicht.
Wer so ne Signatur hat wie du, der sollte schon mehr drauf haben.