Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understanding of Volatile.Read/Write

I'm trying to understand the C# Volatile class.

As i read:

  • The Volatile.Write method forces the value in location to be written to at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to Volatile.Write.

  • The Volatile.Read method forces the value in location to be read from at the point of the call. In addition, any later program-order loads and stores must occur after the call to Volatile.Read.

Is that means the 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);        
    }    
}

the cpu will wait for the commands before Volatile.Write(ref m_flag, 1); before starting to write to m_flag?

And how is that helps the threads synchronization?

like image 734
No Idea For Name Avatar asked Jun 19 '14 12:06

No Idea For Name


People also ask

What is volatile read?

On a uniprocessor system, volatile reads and writes ensure that a value is read or written to memory and not cached (for example, in a processor register). Thus, you can use these operations to synchronize access to a field that can be updated by another thread or by hardware.

What is volatile C#?

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.

Where are volatile variables stored Java memory?

Volatile fields are instance or class (static) variables and are stored in the heap.


2 Answers

the cpu will wait for the commands before Volatile.Write(ref m_flag, 1); before starting to write to m_flag?

Eeeh, kinda. A better way to phrase this is: it's guaranteed that, if any other thread sees m_flag set to 1, they will also see m_value set to 5.

And how is that helps the threads synchronization?

I wouldn't say it helps with synchronization - but it does help with achieving correctness.

If you weren't using volatile reads/writes, it would be possible for the compiler/runtime/cpu to reorder the two instructions in the Thread1 method, and the program would be able to print either 0, 5 or nothing at all.

With the volatile reads/writes, the program will print either 5 or nothing at all, but never 0. Which is the intended behaviour.

like image 57
dcastro Avatar answered Sep 21 '22 01:09

dcastro


How does that help thread synchronization?

It does not help thread synchronization in the sense of setting the order in which their commands execute. It lets you ensure that a concurrent thread observes changes to values in memory in a specific order, in cases when a particular order is important for the logic of your program.

[Does] the CPU wait for the commands before Volatile.Write(ref m_flag, 1); before starting to write to m_flag?

No, the command to write to m_value has already executed. However, its results may not be visible outside the CPU's core - in particular, a thread running on a different core might read an old value from m_value after the command that wrote 5 to it has finished executing. This is because the new value may be in the cache of the CPU, not in the memory.

If you write

m_value = 5;
m_flag = 1;

instead of Volatile.Write(ref m_flag, 1) the other core may see the writes in a different order: first it would see that m_flag became 1, and after that it would see that m_value became 5. If your other thread uses the value of m_flag to judge the validity of m_value, the logic may be broken: for example, Thread2 may occasionally print zero.

like image 29
Sergey Kalinichenko Avatar answered Sep 18 '22 01:09

Sergey Kalinichenko