Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is volatile bool for thread control considered wrong?

As a result of my answer to this question, I started reading about the keyword volatile and what the consensus is regarding it. I see there is a lot of information about it, some old which seems wrong now and a lot new which says it has almost no place in multi-threaded programming. Hence, I'd like to clarify a specific usage (couldn't find an exact answer here on SO).

I also want to point out I do understand the requirements for writing multi-threaded code in general and why volatile is not solving things. Still, I see code using volatile for thread control in code bases I work in. Further, this is the only case I use the volatile keyword as all other shared resources are properly synchronized.

Say we have a class like:

class SomeWorker { public:     SomeWorker() : isRunning_(false) {}     void start() { isRunning_ = true; /* spawns thread and calls run */ }     void stop() { isRunning_ = false; }  private:     void run()     {         while (isRunning_)         {             // do something         }     }     volatile bool isRunning_; }; 

For simplicity some things are left out, but the essential thing is that an object is created which does something in a newly spawned thread checking a (volatile) boolean to know if it should stop. This boolean value is set from another thread whenever it wants the worker to stop.

My understanding has been that the reason to use volatile in this specific case is simply to avoid any optimization which would cache it in a register for the loop. Hence, resulting in an infinite loop. There is no need to properly synchronize things, because the worker thread will eventually get the new value?

I'd like to understand if this is considered completely wrong and if the right approach is to use a synchronized variable? Is there a difference between compiler/architecture/cores? Maybe it's just a sloppy approach worth avoiding?

I'd be happy if someone would clarify this. Thanks!

EDIT

I'd be interested to see (in code) how you choose to solve this.

like image 970
murrekatt Avatar asked Aug 09 '11 11:08

murrekatt


People also ask

Is volatile bool thread safe?

It is not thread safe.

Is volatile useful for threads?

volatile is unnecessary and useless for synchronization between threads. Threading libraries can't be implemented in terms of volatile ; it has to rely on platform-specific details anyway, and when you rely on those, you no longer need volatile .

Can bool be volatile?

In other words, you cannot declare a "pointer to volatile." Simple types such as sbyte , byte , short , ushort , int , uint , char , float , and bool .

Is volatile thread safe C?

In Java volatile creates a memory barrier when it's read, so it can be used as a threadsafe flag that a method has ended since it enforces a happens-before relationship with the code before the flag was set. This is not the case in C.


1 Answers

volatile can be used for such purposes. However this is an extension to standard C++ by Microsoft:

Microsoft Specific

Objects declared as volatile are (...)

  • A write to a volatile object (volatile write) has Release semantics; (...)
  • A read of a volatile object (volatile read) has Acquire semantics; (...)

This allows volatile objects to be used for memory locks and releases in multithreaded applications.(emph. added)

That is, as far as I understand, when you use the Visual C++ compiler, a volatile bool is for most practical purposes an atomic<bool>.

It should be noted that newer VS versions add a /volatile switch that controls this behavior, so this only holds if /volatile:ms is active.

like image 190
Martin Ba Avatar answered Sep 22 '22 03:09

Martin Ba