[Interest] Heavily Commented Example: Simple Single Frontend with Two Backends

Till Oliver Knoll till.oliver.knoll at gmail.com
Mon Oct 22 22:44:05 CEST 2012


Am 22.10.2012 um 16:07 schrieb Jan Kundrát <jkt at flaska.net>:

> On 10/22/12 14:12, Till Oliver Knoll wrote:
>> So the net effect is that the "worker thread" does "one loop too much"
>> - but /eventually/ it will see that m_continue has been set to 'false'
>> and will terminate. And that is exactly what we want and hence "good
>> enough" (no need for protecting the member m_continue with a mutex!).
> 
> Hi Till,
> you don't need a mutex, but you need a guarantee that the compiler will
> recognize that you use that variable for inter-thread synchronization.

Off course I had only single CPU / multicore with synchronised caches in mind (*cough* *cough*).

> Volatile does not do that.

Seriously, I thought "volatile" would at least force the CPU to always read it from (the CPU's own) memory instead of any cache/register?

So the problem would only occur if you really had multiple CPUs with dedicated RAM per CPU, no?


> Qt's QAtomicInt or C++11's std::atomic_bool
> or std::atomic_flag will work fine.

So I understand you basically have to explicitly tell the CPU to fetch and sync the data from RAM by means of "aquire" and "releasing" memory, so it would also work on "real" multi-CPU systems (and dedicated RAM per CPU - but since you say the CPU might also cache the data regardless of "volatile", I assume you also need to "sync" memory in the "shared RAM" case).

However my actual question is: wouldn't that be also the case for /any/ data structure I share between threads? So besides making sure that only one thread modifies the data (by a mutex) I would *also* have to make sure that (possibly) cached instances (in the other CPUs) get invalidated?

Or in other words: wouldn't there be a need for QAtomicString, QAtomicWhatever and any struct or pointer I could think of?

I have actually never bothered (so far ;)) writing an application for multiple CPUs, especially with dedicated RAM (because there I clearly see that you *need* to take measures in your code to sync the RAM and caches).

However I dare to put the following statement: As long as you only consider "Intel Desktop"-like CPUs with *shared RAM", even if you have multiple CPUs (not just "cores"), when you specify your shared data ("shared between threads") as "volatile", you are fine.

Is that wrong? Uh oh, and now I'm totally confused, because I never bothered to declare e.g. shared classes (or rather their member data) as "volatile". I mean how is sharing a simple boolean (or integer) different from sharing say an instance of a QString? Isn't there then always the danger that one thread sees (partly) outdated data (coming from a stale cache) if you don't explicitly use "memory aquire" and "-release"?

> 
> A good read of what volatile actually is for and how it differs from
> these atomic variables is available from the links I posted in my other
> reply to this thread. 

I need to read them ;)

Thanks,
  Oliver


More information about the Interest mailing list