www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Concurrency Read/Write and Pure

reply Adam <Adam anizi.com> writes:
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)?
Nov 30 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Nov 30 2011
parent Adam <Adam Anizi.com> writes:
Ahh, ok. Thank you, that helps quite a bit.
Dec 01 2011