Home >Backend Development >C++ >Can C# Threads Cache Boolean Values and Ignore Subsequent Changes on Other Threads?
Can Cached Values on Threads Ignore Changes Made on Other Threads?
This question focuses on whether a C# thread can cache a value and disregard subsequent changes made to that value on different threads. Despite common knowledge about race conditions, atomicity, and the use of locks, the inquiry specifically targets scenarios where the .NET runtime might potentially abstract away volatile memory concerns.
Some sources claim that in the following code, the reading thread may cache the initial value of the bool variable "stopping" and never detect its modification, potentially leading to an infinite loop:
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 } } }
However, the validity of this claim is disputed. Critics question whether the .NET runtime would genuinely disregard changes to memory values as alleged. They point out that the given code "almost certainly" works, implying that the claim is unfounded.
The crux of the matter is that the behavior described in the claim is not guaranteed by the .NET specification. While it may work in most cases, it is not assured to do so in all circumstances. Experts in the field of memory models caution against relying on such unreliable outcomes.
Furthermore, a verifiable counter-example has been presented, demonstrating a specific scenario where the code fails as predicted. In the following revised code, "stopping" is declared as volatile to rectify the issue:
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); } }
When run in "release" mode without the volatile keyword, the code enters an infinite loop and continues running indefinitely, even after "stopping" has been set to true. However, adding "volatile" to the "stopping" variable resolves the issue, allowing the loop to exit as intended.
The conclusion is that while the code may often appear to function, it cannot be guaranteed to do so consistently. For robust and reliable multithreaded code, the use of locks or the volatile keyword is strongly advised.
The above is the detailed content of Can C# Threads Cache Boolean Values and Ignore Subsequent Changes on Other Threads?. For more information, please follow other related articles on the PHP Chinese website!