Variable caching

Why is caching in this part of the code complete?

static void Main()
{
  bool complete = false; 
  var t = new Thread (() =>
  {
    bool toggle = false;
    while (!complete) toggle = !toggle;
  });
  t.Start();
  Thread.Sleep (1000);
  complete = true;
  t.Join();        // Blocks indefinitely
}

but in this part is it not?

static void Main()
{
  bool complete = false;
  bool toggle = false; 
  var t = new Thread (() =>
  {
    while (!complete) toggle = !toggle;
  });
  t.Start();
  Thread.Sleep (1000);
  complete = true;
  t.Join();  
}
+5
source share
3 answers

You are performing an unsynchronized stream exchange. Sirens should disappear.

As I understand it, the JIT memory model allows you to read completeonce and store it in a register. For this reason, an update from Main never becomes visible.

Regarding fixing this, the easiest way is to combine access blocking to complete. You can also use Thread.VolatileReadand Thread.VolatileWrite.

+3
source

, , , , , , .

, , . , .

, , , , , .

.

+3

, lambda/delegate - , .

You are delegating access to the modified closure, which can cause a lot of problems, and you apparently found it. Take a look at the answer provided by Jon Skeet here, Access to Modified Closures is not exactly the same problem, but the reason described here also works in your case.

0
source

All Articles