.Net comparison

Can the compiler or processor reorder the following instructions so that the other thread sees a == 0 and b == 1 ?

Assuming int a = 0, b = 0; somewhere.

 System.Threading.Interlocked.CompareExchange<int>(ref a, 1, 0); System.Threading.Interlocked.CompareExchange<int>(ref b, 1, 0); 
+5
source share
3 answers

Not. Using Interlock will signal a full memory fence. "That is, any variable is written before the Interlocked method is Interlocked before the Interlocked method, and any variable is read after the call is made after the call." [1] They use mutable read / write methods to prevent b = 1 to a = 1 .

[1]: Jeffrey Richter: "CLR through C # - Third Edition" Part V Threading, p. 803

+4
source

Of course it is possible. The individual operations that make up the CompareExchange operation cannot be reordered, but two CompareExchange can be reordered in terms of another thread if the thread executing this code cannot observe this behavior.

The synchronization tools for CompareExchange prevent the observed reordering between operations affecting memory cells related to this operation, and not any operations at all, and there is nothing in this code to prevent the compiler or JITter from reordering these two CompareExchange calls entirely (from the point view of another stream).

+3
source

You read too much theory. Yes, this can happen in practice if another thread

 Console.WriteLine("a: {0}, b: {1}", a, b); 

Since String.Format, which is used to format the string, has a signature

  String Format(string fmt, params object[] args) { .... } 

your integers will be copied due to boxing. The only condition that must be true is that the time slice of the threads ends when it has copied a in its unified state. Later, when the thread resumes, both variables are set to one, but your console output will be

 a: 0, b: 1 

The point of view of other values ​​occurs immediately if you work with copies of the values ​​without realizing it. It is for this reason that you usually allow other people to write the correct code without blocking. If you try to debug unlocked code using Console.WriteLine, I wish you the best of luck.

Although a and b are set in order (I don't think the JIT compiler will change your blocked calls), you have no guarantee that other threads will see only two zeros or two. You could try to read b first and see if it matters, then you can print the value of a, but in this case you don't even need the value of any. This should be true, at least for the x86 memory model. This assumption may be violated by weaker memory models such as ARM.

+3
source

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


All Articles