www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.concurrent Tid vector initialization problem

reply Charles Hixson via Digitalmars-d-learn writes:
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.)
Jun 27 2015
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/27/2015 06:00 PM, Charles Hixson via Digitalmars-d-learn 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.)
register(), unregister(), and locate() may be useful: I have a short example in the "Thread names" section here: http://ddili.org/ders/d.en/concurrency.html Ali
Jun 27 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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.
Jun 28 2015
parent reply "Charles Hixson" <charleshixsn earthlink.net> writes:
On Sunday, 28 June 2015 at 09:59:29 UTC, Marc Schütz wrote:
 On Sunday, 28 June 2015 at 01:02:02 UTC, Charles Hixson wrote:
 I'm planning an application where a series of threads each 
 ...gn.  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.
Thanks. That sounds similar to the approach that I had though of, except that you're doing it in a static this(). (I'd have answered sooner, but my D email seems to have died. Only the D groups are currently dead now, though my entire account was dead for a couple of weeks. [AT&T])
Jun 30 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 30 June 2015 at 19:19:43 UTC, Charles Hixson wrote:
 On Sunday, 28 June 2015 at 09:59:29 UTC, Marc Schütz wrote:
 On Sunday, 28 June 2015 at 01:02:02 UTC, Charles Hixson wrote:
 I'm planning an application where a series of threads each 
 ...gn.  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.
Thanks. That sounds similar to the approach that I had though of, except that you're doing it in a static this(). (I'd have answered sooner, but my D email seems to have died. Only the D groups are currently dead now, though my entire account was dead for a couple of weeks. [AT&T])
That `shared static this` isn't really necessary here. I originally had an immutable `allTids`, for which it was necessary.
Jul 01 2015