std.concurrent Tid vector initialization problem

via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 28 02:59:28 PDT 2015


On Sunday, 28 June 2015 at 01:02:02 UTC, Charles Hixson wrote:
> I'm planning an application where a series of threads each need 
> to be aware of the Tids of all the others.  The number won't be 
> known at compile time, but that doesn't seem to change the 
> design.
>
> All I've been able to come up with is a pair of loops, one to 
> spawn the threads, and collect their Tids, and a second for 
> each one to send its Tid to all the others.  receive doesn't 
> seem to want to work with shared Tids.  My original design was 
> to have a file level shared array of Tids, but receive (or 
> possibly send) objected to attempts to use them.  They aren't 
> known until they've been spawned, so I can't pass them as spawn 
> parameters.  Etc.
>
> This seems like a very clumsy initialization design.  Does 
> anyone have a better idea?
>
> (The rough estimate of the number of Tids is six, but that's 
> likely to change from run to run.)

The most elegant solution I can think of is this:

struct Go { }

__gshared const Tid[] allTids;

void myfunc(...) {
     receiveOnly!Go();
     // do the work
}

shared static this() {
     Tid[] tids;
     foreach(thread; threads)
         tids ~= spawn(&myfunc, ...);
     *cast(const(int)[]*) &allTids = tids;
     foreach(tid; allTids)
         tid.send(Go());
}

I believe the cast is not even undefined behaviour, because it's 
not immutable, but I'm not sure. But the const-ness guards 
against accidental modification of `allTids` by a thread.

Alternatively, you could make `allTids` private, provide a public 
getter, and implement the threads in another module.

Or you could simply leave the global array mutable and be careful 
not to modify it.


More information about the Digitalmars-d-learn mailing list