Dir geht es darum, Locks ohne Schaden entziehen zu dürfen.
Auch, aber die ReadWrite-Sache könnte unter Umständen der Performance helfen.
Nein, dein Ausgangspunkt war das schadenfreie Entziehen von Locks!
Du darfst dir aber gerne sogenannte lock-free data-structures anschauen, sowas gibt es inzwischen auch.
Ich weiß, die eine Sache dazu die ich mir angesehen habe, war aber (meiner Meinung nach) Unfug bzw. auch nur nen Lock nur halt anders implementiert.
Ich habe mich damit nicht befasst, aber du kannst ein Problem, welches eine Zugriffssperre erfordert, nicht ohne Zugriffssperre umgehen. Das ist in der Natur der Sache.
Deadlocks geschehen entweder reproduzierbar aus Logikfehlern
Naja, einige Deadlocks die ich schon hatte, waren leider nicht so wirklich reproduzierbar, weil nämlich die Zeit (gerade auf SMP Systemen) auch nen Faktor spielt und das kann man immer so schlecht reproduzieren.
Den zweiten Teilsatz lesen können?
...oder schlecht reproduzierbar durch Race Conditions, also ungenügend/schlecht geschützte Strukturen...Ersteres kann nur durch Nachdenken behoben werden
Das ist mir auch durch den Kopf gegangen, dass Deadlocks ja eigentlich ganz "einfach" zu lösen sind. Das beste gegen Deadlocks ist keine Locks zu benötigen, ansonsten sollte man versuchen das man immer nur einen Lock zur gleichen Zeit haben darf, dann können (eigentlich) auch keine Deadlocks auftreten.
Schlug ich bereits vor, nennt man GIANT_LOCK. Funktioniert und ist schneller als CPU-Festpinnen. Langsamer als gute Granularität.
Das ist Symptombehebung und damit Blödsinn.
Dem muss ich mal wiedersprechen. Ich bin mir jetzt nicht sicher ob man das als Symptom bezeichnen kann, aber z.B. CPU-Bugs die fixed du ja auch nicht (wie auch ), sondern du versuchst das Problem zu umgehen (weiß nicht wie ich es anders sagen soll) und das ist auch kein Blödsinn, sondern einfach nötig.
Ich als Anwendungsprogrammierer muss damit leben, richtig. Ich als Systembesitzer ziehe mir (in der Theorie) ein BIOS-Update. Dieses BIOS-Update aktualisisiert mir bei jedem Systemstart den CPU-Mikrocode und fixt damit das Problem. Ich als Betriebssystementwickler stelle eine solche Schnittstelle dem Systembesitzer zur Verfügung, sodaß dieser die aktualisierten Mikrocodes auch ohne BIOS-Update einspielen kann.
Der Blödsinn liegt darin begründet, dass du
grundlos Sympthombehebung durchführst. Ein CPU-Bug lässt dir keine andere Wahl, es sei denn du baust die CPU selbst.
Aber wenn Du in einem Stück Software einen Fehler findest dann kannst Du den beheben und neu compilieren und gut is.
Ich vermute mal das es schon soetwas gibt, dass man um irgendwelche Fehler in irgendeiner Software drumrumprogrammiert.
Korrekt. Besonders in Produktionsumgebungen, wo man stabile und bekannte Softwareversionen benötigt, wird das so getan. Allerdings trifft das nur dann zu, wenn die zu benutzende Software nicht selbstgeschrieben ist. Kurz: Wenn möglich, wird gefixt. Erst wenn unmöglich oder nicht mehr sinnvoll, wird mit Workarounds gearbeitet.
Ich habe aber halt viele Locks und da kommt dann durchaus mal die Situation auf das Thread A den Lock 1 hat und Lock 2 versucht zu bekommen. Thread B hat Lock 2 und will Lock 1 und solche Situationen sind ab einer gewissen Größe schlecht zu überschauen (jetzt komm mir ja nicht mit Dokumentation ).
Dann solltest du vielleicht dokumentieren, wie du dir gewisse Dinge vorstellst oder es einfach direkt richtig machen. Wenn (b) nicht geht, musst du halt doch (a) machen.
Wenn du weißt, dass dein Design kaputt ist, warum machst du dann keins, welches weniger kaputt ist?
Das ist so "meine" Quelle für Deadlocks, vorallem welche die sich schlecht bis gar nicht finden lassen (da sie nie auftreten oder so selten das man sie nicht reproduzieren kann).
Das nennt man Race-Condition.
Na scheinbar ist das doch Dein Probem, wie Du ja selber schreibst.
Wo? Ich meine es geht darum das man Lock 1 bekommt, dann Lock 2 und nicht erst Lock 1 sondern Lock 2 freigibt, oder? Man gibt die Locks nach dem LIFO-Prinzip wieder frei.
Daran halte ich mich!
Offensichtlich nicht immer oder nicht gut genug. Und wenn CPU1 erst Lock 1 und dann Lock 2 anfragt und CPU2 genau umgekehrt, dann hast du ein anderes wichtiges Prinzip verletzt.
Ich hatte mal mit ner Dokumentation angefangen, wo ich beschrieben habe was die Parameter machen/beinhalten, aber ich habe irgendwann festgestellt, das ich einfach nur aus nem alles sagenden Namen nen Satz gemacht habe, also zwecklos.
Was ich machen müsste, ist die Funktionalität einer Funktion zu beschreiben, aber auch das kann man bei mir aus dem Namen ableiten, bleibt nur noch das ich aufschreiben sollte, welche Locks benutzt werden.
Blödsinn. Was offensichtlich ist, muss man nicht unbedingt dokumentieren. Du erklärst Programme ja hoffentlich auch nicht mehr zeilenweise?
Wie wäre es mit einer Block-Übersicht, die die einzelnen Abhängigkeiten der Einzelteile untereinander dokumentiert? Genau diese Abhängigkeiten (=Schnittstellen) musst du definieren. Das machst du rekursiv von oben und soweit wie nötig. Also die einzelnen Blöcke wieder soweit einzeln dokumentieren, bis man den Überblick wieder hat. Zu den Schnittstellen gehören die zu schützenden Datenstrukturen (soweit vorhanden) und daraus ergibt sich innerhalb einer Ebene auf einen Blick, welche Locks wo verwendet werden.
Und sowas macht man parallel mit dem Projekt - geht einfach und schnell nebenher, wenn etwas funktioniert - , bei verteilten Großprojekten macht man das vorher in der Designphase.
Aber auch ne Dokumentation hilft nicht, wenn man Fehler an der falschen Stelle sucht (War mein Problem, habe alles auf ne Deadlock geschoben, aber der Code hatte nen Fehler)
Darum dokumentiert man. Entweder, um gewisse Fehler von vornherein ausschließen zu können (oder stark eingrenzen zu können), oder um "mal schnell" in der Logik nachzuschauen, ob das überhaupt so geht. Die Logikprüfung muss
immer aus der Vogelperspektive sehen, denn selbst wenn alle Einzelteile logisch fehlerfrei sind, muss es das Gesamtsystem noch lange nicht sein.
Gruß,
Svenska