Thread.Sleep (0) funktioniert nicht wie beschrieben?

9

Ich lese gerade diesen ausgezeichneten Artikel zum Threading und lese den folgenden Text:

  

Thread.Sleep (0) gibt die aktuelle Zeitscheibe des Threads sofort frei und übergibt die CPU freiwillig an andere Threads.

Ich wollte das testen und unten ist mein Testcode:

%Vor%

Die Funktionen, die threadPoints und threadNewLines ausführen:

%Vor%

Wenn ich Thread.Sleep (0) richtig verstehe, sollte die Ausgabe in etwa so aussehen:

%Vor%

Aber ich bekomme das als Ausgabe:

%Vor%

Da der eingangs erwähnte Artikel von vielen Programmierern sehr empfohlen wird, kann ich nur davon ausgehen, dass mein Verständnis von Thread.Sleep (0) falsch ist. Wenn also jemand klären könnte, wäre ich sehr dankbar.

    
Jordy 28.06.2013, 13:11
quelle

5 Antworten

2

Was thread.sleep (0) ist, um die CPU freizugeben, um mit anderen Threads umzugehen, aber das bedeutet nicht, dass ein anderer Thread nicht der aktuelle sein könnte. Wenn Sie versuchen, den Kontext an einen anderen Thread zu senden, versuchen Sie, eine Art Signal zu verwenden.

    
saamorim 28.06.2013 13:20
quelle
1

Wenn Sie Zugriff auf einen Computer (oder vielleicht eine VM) mit nur einem einzelnen Prozessor / Prozessor haben, versuchen Sie, den Code auf diesem Computer auszuführen. Sie können überrascht sein, wie die Ergebnisse variieren. Nur weil sich zwei Threads auf die gleiche Variable "s" beziehen, heißt das nicht, dass sie sich auf denselben Wert zur selben Zeit beziehen, aufgrund verschiedener Caching-Ebenen, die bei modernen CPUs mit mehreren Kernen (und sogar nur mit parallelen Pipelines) auftreten können . Wenn Sie unabhängig von den Caching-Problemen sehen möchten, wie das Rendern funktioniert, versuchen Sie, jeden s += -Ausdruck in eine lock -Anweisung einzufügen.

    
Dan Bryant 28.06.2013 13:22
quelle
1

Wenn Sie die Breite der Konsole um das 5-fache vergrößern würden, dann würden Sie sehen, was Sie erwarten, da die Linien die Konsolenbreite nicht erreichen. Das Problem ist eine Zeitscheibe ist eigentlich sehr lang. Um den erwarteten Effekt mit der normalen Konsole zu erzielen, müssten Sie den Points-Thread verlangsamen, ohne Sleep zu verwenden. Statt while (true) loop probiere das

%Vor%

Um den Thread noch langsamer zu machen, ersetzen Sie Nummer 10 durch eine größere Zahl.

    
Dialecticus 23.07.2013 12:47
quelle
0

Der nächste Thread, den der Prozessor behandelt, ist ein zufälliger Thread und es könnte sogar derselbe Thread sein, den Sie gerade Thread.Sleep (0) genannt haben. Um sicherzustellen, dass der nächste Thread nicht derselbe Thread ist, können Sie Thread.Yield () aufrufen und das Ergebnis der Rückgabe überprüfen - wenn os einen anderen Thread hat, der auf true ausgeführt werden kann, wird stattdessen false zurückgegeben.

    
Andriy Vandych 23.07.2013 09:36
quelle
-1

Sie sollten (fast) Threads niemals abbrechen . Die beste Praxis ist, ihnen zu signalisieren, dass sie sterben müssen (Selbstmord begehen).

Dies wird normalerweise erreicht, indem eine boolesche Variable gesetzt wird, und die Threads sollten ihren Wert prüfen, ob sie fortgesetzt oder nicht ausgeführt wird.

Sie legen eine Stringvariable namens "s" fest. Sie werden unter Rennbedingungen leiden. String ist nicht Thread-sicher . Sie können die Operationen, die sie manipulieren, in eine Sperre einschließen oder einen integrierten thread-sicheren Typ verwenden.

Achten Sie immer darauf, in der Dokumentation zu wissen, ob die von Ihnen verwendeten Typen threadsicher sind.

Aus diesem Grund können Sie sich nicht auf Ihre Ergebnisse verlassen, da Ihr Programm nicht threadsicher ist . Wenn Sie das Programm mehrmals ausführen, ist es wahrscheinlich, dass Sie verschiedene Ausgaben erhalten.

Hinweis: Wenn Sie einen booleschen Wert verwenden, um einen Zustand zum Abbrechen von Threads freizugeben, stellen Sie sicher, dass er als flüchtig markiert ist. JIT optimiert möglicherweise den Code und sieht sich niemals den geänderten Wert an.

    
Luis Filipe 28.06.2013 13:19
quelle

Tags und Links