Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using volatile for one-way communication between threads in .NET

I've read a fair amount of posts on the subject, and I think I finally understand how the volatile keyword works in C#. Still I wanted to ask here just to make sure I understand the concepts properly. Consider the following code:

class ThreadWrapper
{
  public bool Enabled { get; set; }

  private void ThreadMethod()
  {
    while (Enabled) { // ... Do work }
  }
}

From what I understand, if another thread were to set Enabled=false, the original thread may not actually see this change right away (or perhaps ever?). To make sure the compiler doesn't optimize access to the Enabled property and rely on cached values, changing the code as follows should fix things.

  public bool Enabled { get {return mEnabled;} set {mEnabled=value;} }
  private volatile bool mEnabled;

Now whenever the Enabled value is read, it is guaranteed to get its most current value, correct? If so, I should be able to use it as a simple signal or flag (like I have above).

As another example, consider the following:

class C
{
  private volatile int i;
  private volatile bool enabledA;
  private volatile bool enabledB;

  void ThreadA()
  {
    i = 0; // Reset counter
    while (enabledA)
    {
      // .. Do some other repeated work
      if (i > 100)
      {
        // .. Handle threshold case
      }
    }
  }

  void ThreadB()
  {
    while (enabledB)
    {
      // .. Do work
      if (condition) // Some condition occurs that we want to count
      {
        i++;
      }
    }
  }
}

For simple inter-thread communication like this, is volatile satisfactory here? I understand that i++ isn't an atomic operation, but if one thread is doing all the incrementing and another simply wants to read it to see if it reaches a certain threshold, we're okay right?

Edit: I course I found another similar question with detailed answers after the fact.

like image 846
Jeremy Avatar asked Nov 03 '11 00:11

Jeremy


People also ask

Is volatile thread safe C#?

Although the volatile keyword can help you in thread safety in certain situations, it is not a solution to all of your thread concurrency issues. You should know that marking a variable or an object as volatile does not mean you don't need to use the lock keyword.

What is the use of volatile in 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.


2 Answers

I believe you are correct.

MSDN's article on the volatile keyword uses this very same technique in its example.

like image 176
rossipedia Avatar answered Sep 19 '22 11:09

rossipedia


Yes, this should be safe, and is one of the intended uses of the volatile keyword. Note however that you should not loop merely to test the condition; if you want to simply wait for it to change, use a proper synchronization primitive to avoid wasting CPU time. Note also that this technique only works because you have only one thread writing; if multiple threads try to increment the counter, you may lose counter hits (because the read-modify-write is not atomic).

like image 31
bdonlan Avatar answered Sep 19 '22 11:09

bdonlan