10-Jun-2013 17:38, Sergei Nosov пишет:
Hi!

I'm puzzled with what's the difference between shared and __gshared.
Until now I've (mistakenly) considered that shared variables are free
from low-level data races. I.e. the operations with shared data are
atomic. And that __gshared is the "usual" (in C++ sense) shared data.


Is this how shared is supposed to work? If so, how is the __gshared
different from it? Does it not guarantee that the result of a write is
instantly visible to all threads? If so, does this difference really
matter?

Simply put __gshared is a hack to get exactly the same as plain global in C. Nothing about memory visibility is guaranteed unless explicitly enforced with some core.sync/core.atomic primitives. Worse yet it pretends to be the usual thread-local variable in a type system (hence a hack).

Shared is above all a transitive qualifier so if you have say

struct S{
        char* ptr;
        int len;
}

shared S s;

s.ptr is also typed as shared(char*)

Secondly shared type should strongly limit the scope of operations you can do with it - for instance writing normal (TLS) pointer to S.ptr field. This makes it easy to separate what's shared between threads and what is not. In a certain sense it actively prevents inadvertent mixing of thread-local and global state.

Continuing with limitations: for shared classes and structs you can only call shared methods on a shared instance. In this case think of shared as "thread-safe" because currently you most likely will have to cast you way though and maintain it by hand.

Third is as you notated it's backed by the same simple global data visible by all threads. This is the same for both.

Now there was a discussion on it recently which indicates that shared data might lose it's built-in ops to prevent confusion and require folks to just use core.atomic directly for lock-free or alternatively cast+mutex for lock-based.

--
Dmitry Olshansky

Reply via email to