Concurrency Read/Write and Pure
Jonathan M Davis
jmdavisProg at gmx.com
Wed Nov 30 20:53:56 PST 2011
On Thursday, December 01, 2011 04:23:39 Adam wrote:
> Howdy.
>
> So, I'm reading through "The D Programming Language" book, and I had
> some questions on concurrency in D, and maybe with some emphasis on
> programming in general.
>
> I present my question with a hypothetical case:
> I have two threads and, ideally, one structure. The structure is
> large enough that passing it in its entirety is non-trivial, and
> that a synchronized understanding of the data at any given point of
> time between the two threads is ideal (that is, it's not desirable
> for one thread to update another with changes to the structure).
> One thread writes / makes changes to the structure's contents.
> The other only reads the structure's contents (as well as its
> topology)
>
> Now, I could make this structure global with respect to both threads
> (shared), which would introduce the need to synchronize access to it
> for both threads (using synchronized, mutexes, etc).
>
> However, for all intents and purpose, the writing thread "owns" the
> data - it's the only thread allowed to make changes to it.
>
> Given that, and the guarantees made by "pure," is there a scheme in
> D to fit this explicit one-thread-reads, one-thread-writes scenario
> that doesn't require a mutex / synchronization between the two
> (since only one will be changing it)?
To have an object on two threads without it being shared essentially requires
that you cast away shared on one or both of the threads, which more or less
subverts the type system, but it works as long as _you_ guarantee that only
one thread actually has the object or put whatever else needs to be in place
to ensure that manipulating it from two or more threads doesn't cause issues
(such as using mutexes).
If you don't care that the object may not be in a completely up-to-date state
(that is, if you read it in the reader thread while it's being written to in
the writer thread), then it's a non-issue, but if you want to make sure that
the reader thread never reads while the writer thread is writing, then you're
going to have to use mutexes or synchronized blocks or the like. Otherwise,
there's nothing which stops the reader thread from reading while the writer
thread is writing - _especially_ if you've cast away shared, since then the
compiler treats the object as if it were thread-local. Without that
synchronization, you have no way of guaranteeing that the writes are
essentially atomic, and if they're not atomic, then the reader thread can read
while the writer thread is writing.
Pure really doesn't enter into this at all. A pure function whose parameters
aren't immutable (or implicitly convertible to immutable) doesn't make any
guarantees beyond the fact that it can't access global mutable state or call
any non-pure functions. If all of the parameters are immutable or implicitly
convertible to immutable, then when multiple calls are made within a single
expression (and maybe statement - I don't recall for sure, but certainly not
over multiple statements), only a single call will be made - which is the
primary optimization that pure provides.
Not only does that have nothing to do with threading, but if the parameters
are immutable, then you can't use a mutable object with them as you seem to be
looking to do. And if the parameters are implicitly convertible to immutable
rather than actually immutable (e.g. with a struct or int or some other value
type), then a copy would be being made, which doesn't sound like what you're
trying to do.
Really, to do what you're trying to do should be done with a shared object -
probably with the type being synchronized (either that, or it needs to use one
or more mutexes). Pure isn't going to help you.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list