Understanding Volatile.Read/Write

I am trying to understand the volatile C # class.

As I read:

  • The Volatile.Write method forces to write the value in the location to the point of call. In addition, any earlier programmatic order of downloads and repositories must occur before the Volatile.Write function is called.

  • The Volatile.Read method forces to read the value in the location of at the time of the call. In addition, any subsequent downloads of software orders and stores should occur after calling Volatile.Read.

This means that in the case of:

 internal sealed class ThreadsSharingData { private Int32 m_flag = 0; private Int32 m_value = 0; // This method is executed by one thread public void Thread1() { // Note: 5 must be written to m_value before 1 is written to m_flag m_value = 5; Volatile.Write(ref m_flag, 1); } // This method is executed by another thread public void Thread2() { // Note: m_value must be read after m_flag is read if (Volatile.Read(ref m_flag) == 1) Console.WriteLine(m_value); } } 

cpu will wait for a command before Volatile.Write(ref m_flag, 1); before you start writing in m_flag ?

And how does this help thread synchronization?

+8
c # volatile thread-synchronization
source share
2 answers

the processor will wait for the command before Volatile.Write (ref m_flag, 1); before you start writing to m_flag?

Eeeh, kinda. The best way to express this is: it guaranteed that if any other thread sees that m_flag set to 1, they will also see that m_value set to 5.

And how does this help thread synchronization?

I would not say that it helps with synchronization, but it helps in achieving correctness.

If you did not use mutable reads / writes, it would be possible for the / runtime / cpu compiler to reorder the two instructions in Thread1 and the program could print either 0, 5 or nothing.

Using volatile reads / write, the program will print either 5, or nothing at all, but there will never be 0. What is the intentional behavior.

+4
source share

How does this help thread synchronization?

This does not help synchronizing threads in the sense of setting the order of execution of their commands. This ensures that a parallel thread observes changes in memory values ​​in a specific order, in cases where a specific order is important to your program logic.

[Does] The CPU expects a command before Volatile.Write(ref m_flag, 1); before you start writing to m_flag ?

No, the command to write to m_value has already been completed. However, its results may not be displayed outside the CPU core, in particular, a thread running on another core may read the old value from m_value after the team that wrote 5 completed execution. This is because the new value may be in the CPU cache, and not in memory.

If you write

 m_value = 5; m_flag = 1; 

instead of Volatile.Write(ref m_flag, 1) other core can see the entries in a different order: first, it will see that m_flag become 1 , and after that it will see that m_value become 5 . If your other thread uses the m_flag value to evaluate the validity of the m_value , the logic may be broken: for example, Thread2 can sometimes print zero.

+3
source share

All Articles