Domanda

I have a volatile bool 'play' flag in my class that is being set by one thread and being read by another thread.

Do I need to synchronize the calls to that flag? for example in this function:

void stop() 
{
   play = false;
}

In windows they have the _InterlockedExchange and OSX has OSAtomicAdd64Barrier, I've seen those functions being used with shared primitives, do I need them?

Thank you

È stato utile?

Soluzione 2

Depends:

If you are on a CPU that has total store order memory model (eg x86 / x64) or any machine with only 1 CPU core, then the answer to your question is no given that you state that only 1 thread writes to the flags, and barrier directives are probably optimized away anyway on x86. If you compile the same code on a CPU that has a relaxed memory model, then the situation changes, and you may then find code that works perfectly on an x86 develops some bizarre and difficult to reproduce bugs if you compile and run it on an ARM or PPC for example

The volatile directive prevents the write being cached somewhere, and may mean that the reading thread sees the write much sooner than it would in the volatile directive weren't there. Whether you want to use this depends on how important this interval is

Altri suggerimenti

Yes, and volatile does not in any way imply thread safe or atomic. Use std::mutex and std::unique_lock etc if you can, not the platform specifics. std::atomic is good choice -- maybe even best in this case.

It depends on whether there is any other data that is shared between the threads. The problem with threads is that one thread may see writes from a different thread in a different order than the thread originally made them in. In that case you need to use some kind of _Interlocked*/Atomic function or locks (in both threads), they guarantee that all changes made before the flag become visible to the other thread.

If there is no other shared data (or only read-only shared data), or you are running on x86, using just volatile should also work. However that it works is in a sense only accidentally, and not guaranteed by any standard, so if your platform supports it it is still advised to use some form of Atomic/interlocked/etc. In the future (i.e. once there is good compiler support) you should use C++11's std::atomcic as that will be portable between platforms.

You should not be using a bare non-volatile variable, if you do that the compiler may decide to optimize the check away. volatile has very little to do with caching as camelccc suggests.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top