Shared
Steven Schveighoffer
schveiguy at yahoo.com
Mon Aug 2 04:34:08 PDT 2010
On Sun, 01 Aug 2010 12:46:58 -0400, dsimcha <dsimcha at yahoo.com> wrote:
> == Quote from dsimcha (dsimcha at yahoo.com)'s article
>> I've reread the relevant TDPL chapter and I still don't quite
>> understand the
>> following:
>> 1. What is shared? Is it simply a piece of syntactic salt to make it
>> hard to
>> share data across threads by accident, or is there more to it?
>> 2. Is it fully or mostly implemented?
>
> Sorry, accidentally submitted the post before I was done.
>
> 3. How does casting to and from shared work? Under what circumstances
> can
> unshared data be cast to shared? Under what circumstances can shared
> data
> implicitly be cast to unshared?
Let me preface this by saying I don't actually use shared on a daily
basis, but I'll try and respond how I think it works:
1. It indicates to the compiler that multiple threads have direct access
to the data. But more importantly, the *lack* of shared means that
exactly one thread has direct access to the data. I see shared not as
great a feature as unshared is. For an example of optimizations that can
be had with unshared data, see the LRU cache for lock-free array appending.
I think in terms of technical details, reading from/writing to a shared
piece of data requires either a lock, or the compiler will insert a memory
barrier around the write to ensure the write is atomic as long as the data
written is small enough (I'm very fuzzy on these details, I use the term
memory barrier in complete ignorance). Declaring a global variable shared
also makes it a true global (not thread-local). I don't know what was
decided on for shared classes/structs, I vaguely remember that the
consensus was to require declaring the entire class shared at class
definition, but I could be wrong.
2. I do not think it's fully implemented, but I think the intention is
that it's fully implemented, so submit bugs against what it doesn't do if
you find any.
3. *NO* implicit casting of shared<->unshared is allowed for references.
To do so would violate the shared transitivity. It is ok to copy
value-types to/from shared. Think of the relationship between unshared
and shared in the same way as the relationship between mutable and
immutable.
I think you can cast shared to unshared if you *know* that no other thread
will be able to access the data pointed at by the shared value. For
instance, you can never take a reference to a shared global and cast that
reference to unshared, because globals are always available to all threads.
You can cast unshared to shared if you know that you have no other
unshared references to the same data in your local thread. This one can
be much easier to prove.
Neither cast is statically checked or verified, it's up to you as the
programmer to ensure these properties.
-Steve
More information about the Digitalmars-d
mailing list