Ich hatte eine Diskussion mit einem Teamkollegen über das Sperren in .NET. Er ist ein wirklich intelligenter Kerl mit langjähriger Erfahrung sowohl in der nieder- als auch in der höheren Programmierung, aber seine Erfahrung mit der niedrigeren Programmierung übertrifft meine bei weitem. Jedenfalls argumentierte er, dass das Sperren in .NET auf kritischen Systemen, die unter hoher Last stehen, wenn möglich vermieden werden sollte, um die zugegebenermaßen geringe Möglichkeit eines "Zombie-Threads" zu vermeiden, der ein System zum Absturz bringen könnte. Ich benutze regelmäßig das Sperren und wusste nicht, was ein "Zombie-Thread" war, also fragte ich nach. Der Eindruck, den ich aus seiner Erklärung gewonnen habe, ist, dass ein Zombie-Thread ein Thread ist, der beendet wurde, aber auf irgendwie noch einige Ressourcen festhält. Ein Beispiel, das er nannte, wie ein Zombie-Thread ein System zerstören könnte, war ein Thread, der nach dem Sperren eines Objekts einen bestimmten Vorgang startet und dann irgendwann vor der Freigabe des Sperre beendet wird. Diese Situation hat das Potenzial, das System zum Absturz zu bringen, weil schließlich Versuche, diese Methode auszuführen, dazu führen, dass die Threads alle darauf warten, Zugriff auf ein Objekt zu erhalten, das nie zurückgegeben wird, weil der Thread, der das gesperrte Objekt verwendet, tot ist.
Ich denke, ich habe das Wesentliche verstanden, aber falls ich daneben liege, lass es mich bitte wissen. Das Konzept erschien mir logisch. Ich war nicht vollständig überzeugt, dass dies tatsächlich in .NET passieren könnte. Ich habe zuvor nie von "Zombies" gehört, aber ich erkenne an, dass Programmierer, die in tieferen Ebenen gearbeitet haben, ein besseres Verständnis von Rechnergrundlagen (wie dem Threaden) haben. Ich sehe definitiv den Wert des Sperrens, habe aber auch viele erstklassige Programmierer gesehen, die das Sperren nutzen. Ich habe auch nur begrenzte Fähigkeit, dies für mich selbst zu bewerten, weil ich weiß, dass die lock(obj)
-Anweisung nur ein syntaktischer Zucker für ist:
bool lockWasTaken = false;
var temp = obj;
try { Monitor.Enter(temp, ref lockWasTaken); { body } }
finally { if (lockWasTaken) Monitor.Exit(temp); }
und weil Monitor.Enter
und Monitor.Exit
als extern
markiert sind. Es scheint vorstellbar, dass .NET eine Art Verarbeitung durchführt, die Threads vor der Exposition gegenüber Systemkomponenten schützt, die solche Auswirkungen haben könnten, aber das ist rein spekulativ und wahrscheinlich nur darauf zurückzuführen, dass ich noch nie von "Zombie-Threads" gehört habe. Daher hoffe ich, hier Feedback dazu zu bekommen:
- Gibt es eine klarere Definition eines "Zombie-Threads" als die, die ich hier erklärt habe?
- Können Zombie-Threads in .NET auftreten? (Warum/Warum nicht?)
- Falls zutreffend, wie könnte ich in .NET die Erstellung eines Zombie-Threads erzwingen?
- Falls zutreffend, wie kann ich das Sperren nutzen, ohne ein Szenario mit Zombie-Threads in .NET zu riskieren?
Aktualisierung
Ich habe diese Frage vor etwas mehr als zwei Jahren gestellt. Heute ist dies passiert: