Heim >Backend-Entwicklung >C++ >Kann ein C#-Thread Wertänderungen von anderen Threads ignorieren?
Diese Frage untersucht eine mögliche Anomalie im C#-Threading-Verhalten, die nichts mit Rennbedingungen oder der Notwendigkeit von Sperren zu tun hat. Die Sorge besteht insbesondere darin, ob ein Thread einen Wert zwischenspeichern und an diesem Wert in anderen Threads vorgenommene Änderungen ignorieren kann, was möglicherweise zu unerwartetem Verhalten führt.
Es wird angenommen, dass die NET-Laufzeitumgebung, die den Speicher verwaltet, dieses Problem mildert. Einige Literaturstellen behaupten jedoch etwas anderes und behaupten, dass bestimmte Codestrukturen, wie die folgenden, zu Endlosschleifen führen können:
class BackgroundTaskDemo { private bool stopping = false; static void Main() { BackgroundTaskDemo demo = new BackgroundTaskDemo(); new Thread(demo.DoWork).Start(); Thread.Sleep(5000); demo.stopping = true; } static void DoWork() { while (!stopping) { // Do something here } } }
Gemäß den Artikeln, auf die verwiesen wird (http://www.yoda.arachsys.com/ csharp/threads/volatility.shtml , http://softwareengineering.stackexchange.com/questions/104757/is-a-string-property-itself-threadsafe) kann der lesende Thread den Anfangswert der Stoppvariablen zwischenspeichern, wodurch alle nachfolgenden Aktualisierungen unsichtbar werden und der Thread dazu führt läuft auf unbestimmte Zeit.
Experten für Speichermodellierung bestehen jedoch darauf, dass ein solches Verhalten nicht durch die C#-Spezifikation garantiert wird. Während der bereitgestellte Code normalerweise ordnungsgemäß funktioniert, basiert er auf plattform- und compilerspezifischen Optimierungen und nicht auf konkreter Sprachsemantik.
Um das Problem weiter zu veranschaulichen, betrachten Sie den folgenden geänderten Code:
using System.Threading; using System; static class BackgroundTaskDemo { //make this volatile to fix it private static bool stopping = false; static void Main() { new Thread(DoWork).Start(); Thread.Sleep(5000); stopping = true; Console.WriteLine("Main exit"); Console.ReadLine(); } static void DoWork() { int i = 0; while (!stopping) { i++; } Console.WriteLine("DoWork exit " + i); } }
Mit dieser Änderung gibt der Code vorhersehbar „Hauptausgang“ aus, aber die DoWork-Methode läuft auf unbestimmte Zeit weiter. Dieses Gegenbeispiel zeigt, dass die C#-Laufzeit trotz anfänglicher Vermutungen nicht immer Konsistenz bei Wertaktualisierungen über Threads hinweg garantiert.
Um diese Mehrdeutigkeit aufzulösen, kann das Schlüsselwort volatile auf die Stoppvariable angewendet werden. Der flüchtige Modifikator erzwingt den atomaren Zugriff auf die Variable und verhindert so, dass zwischengespeicherte Werte tatsächliche Aktualisierungen verdecken.
Das obige ist der detaillierte Inhalt vonKann ein C#-Thread Wertänderungen von anderen Threads ignorieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!