Memory Model and ThreadPool

I have one NonVolatileTest class:

public class NonVolatileTest 
{
    public bool _loop = true;
}

and I have two code examples:

1

private static void Main(string[] args)
{
    NonVolatileTest t = new NonVolatileTest();

    Task.Run(() => { t._loop = false; });

    while (t._loop) ;
    Console.WriteLine("terminated");

    Console.ReadLine();
}

2:

private static void Main(string[] args)
{
    NonVolatileTest t = new NonVolatileTest();

    Task.Run(() => { t._loop = false; });

    Task.Run(() =>
        {
            while (t._loop) ;
            Console.WriteLine("terminated");
        });

    Console.ReadLine();
}

In the first example, everything works as expected, and the while loop never ends, but in the second example everything works, as stated, the _loop field is mutable.

Why?

PS. VS 2013, .NET 4.5, x64 Release Mode and Ctrl + F5

Hypothesis:

This error may be related to TaskScheduler. I think, before the JIT poses a second task to compile and run, the first task has been completed, so the JIT takes on a changed value.

+4
source share
2 answers

# 5 ( # 4), 10.5.3 - Volatile Fields, :

, , , . , , , , , (§8.12). , . :

( )

, ( - ).

, -, ( ), .


, , , , :

  • , ,
  • , , .
  • , , .

, " ", " this", .

, .

, .

, , -.

+2

: http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/

" .NET" : " , .NET ".

, . , , , "false".

": 0", .

:

private static void Main(string[] args)
{
    NonVolatileTest t = new NonVolatileTest();

    Task.Run(() =>
    {
        var i = 0;
        while (t._loop)
        {
            i++;
        }
        Console.WriteLine("terminated: {0}", i);
    });
    //add delay here
    Task.Run(() => { t._loop = false; });

    Console.ReadLine();
}

, ​​ Thread.Sleep(1000), , (true), , , .

-1

Source: https://habr.com/ru/post/1612749/


All Articles