Heim >Backend-Entwicklung >C++ >Können C#-Threads boolesche Werte zwischenspeichern und nachfolgende Änderungen in anderen Threads ignorieren?

Können C#-Threads boolesche Werte zwischenspeichern und nachfolgende Änderungen in anderen Threads ignorieren?

Susan Sarandon
Susan SarandonOriginal
2025-01-05 10:26:44745Durchsuche

Can C# Threads Cache Boolean Values and Ignore Subsequent Changes on Other Threads?

Können zwischengespeicherte Werte in Threads an anderen Threads vorgenommene Änderungen ignorieren?

Diese Frage konzentriert sich darauf, ob ein C#-Thread einen Wert zwischenspeichern und ignorieren kann Nachfolgende Änderungen an diesem Wert in verschiedenen Threads. Trotz allgemeiner Kenntnisse über Race-Bedingungen, Atomizität und die Verwendung von Sperren zielt die Untersuchung speziell auf Szenarien ab, in denen die .NET-Laufzeit möglicherweise Bedenken hinsichtlich des flüchtigen Speichers abstrahiert.

Einige Quellen behaupten, dass im folgenden Code die Lesart Der Thread kann den Anfangswert der Bool-Variablen „stoppen“ zwischenspeichern und ihre Änderung nie erkennen, was möglicherweise zu einer Endlosschleife führt:

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
        }
    }
}

Die Gültigkeit dieser Behauptung ist jedoch umstritten. Kritiker bezweifeln, dass die .NET-Runtime Änderungen an Speicherwerten tatsächlich wie behauptet ignorieren würde. Sie weisen darauf hin, dass der angegebene Code „mit ziemlicher Sicherheit“ funktioniert, was impliziert, dass die Behauptung unbegründet ist.

Der Kern der Sache ist, dass das in der Behauptung beschriebene Verhalten nicht durch die .NET-Spezifikation garantiert wird. Obwohl dies in den meisten Fällen funktioniert, ist dies nicht unter allen Umständen gewährleistet. Experten auf dem Gebiet der Speichermodelle warnen davor, sich auf solche unzuverlässigen Ergebnisse zu verlassen.

Darüber hinaus wurde ein überprüfbares Gegenbeispiel vorgestellt, das ein spezifisches Szenario demonstriert, in dem der Code wie vorhergesagt fehlschlägt. Im folgenden überarbeiteten Code wird „Stoppen“ als flüchtig deklariert, um das Problem zu beheben:

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);
    }
}

Wenn der Code im „Release“-Modus ohne das Schlüsselwort volatile ausgeführt wird, tritt er in eine Endlosschleife ein und läuft auf unbestimmte Zeit weiter. auch nachdem „stopping“ auf „true“ gesetzt wurde. Durch Hinzufügen von „volatile“ zur Variable „stopping“ wird das Problem jedoch behoben, sodass die Schleife wie vorgesehen beendet werden kann.

Die Schlussfolgerung ist, dass der Code zwar oft scheinbar funktioniert, dies jedoch nicht garantiert werden kann konsequent. Für robusten und zuverlässigen Multithread-Code wird die Verwendung von Sperren oder dem Schlüsselwort volatile dringend empfohlen.

Das obige ist der detaillierte Inhalt vonKönnen C#-Threads boolesche Werte zwischenspeichern und nachfolgende Änderungen in anderen Threads ignorieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn