how to handle shared arrays?

Jonathan M Davis jmdavisProg at gmx.com
Thu Jun 21 15:34:08 PDT 2012


On Thursday, June 21, 2012 21:00:32 maarten van damme wrote:
> I want to have two threads. One parses some content ever half hour and
> the other continuously parses commands passed from the first thread.
> When the second thread finished something it should send the results
> back to the first thread who'll present it to the user.
> The messages the second thread needs to send back is under the form of
> an array of a struct.
> 
> Right now I'm trying something like this:
> shared (T[]) mods=cast(shared (T[]))modifications.dup;
> send(tid, mods);
> 
> This gives me a rather odd-looking errormessage:
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: function
> core. stdc.string.memcpy (void* s1, const(void*) s2, uint n) is not
> callable using arg ument types (ubyte[20u]*,shared(T[])*,uint)
> C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: cannot
> implici tly convert expression (& rhs) of type shared(T[])* to const(
> void*)
> 
> How should I handle arrays that I will need to send back to another thread?
> Excuse me for all those questions, I'm really having a hard time
> grasping the D threading model.

When you send reference types across threads via std.concurrency, they need to 
either be shared or immutable (which is implicitly shared).

If it's shared, it _could_ be on both threads, or it could be one thread 
casting it to shared, passing it across, and the other thread casting away 
shared (in which case, the original thread must _not_ keep a reference to that 
data). However, IIRC while shared is _supposed_ to work with send and receive, 
it doesn't right now.

If it's immutable, it _could_ be on both threads, but if it is, all of the 
references to it must be immutable (which isn't necessarily the case if you 
cast to immutable rather than iduping or constructing the object as 
immutable). If you're passing it across threads, then you either idup it to 
pass a copy across, or you cast it to immutable (std.exception.assumeUnique 
does this with the advantage of documenting that you're saying that you're 
assuming that that's the only reference to that data) and pass it across. If 
you cast to immutable and pass it across, you can then either keep it as 
immutable on the other side, or you can cast away immutable (but if you cast 
away immutable, then it _must_ have been constructed as mutable on the 
original thread, because casting away immutable on something that's actually 
immutable or it's going to result in undefined and buggy behavior).

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list