digitalmars.D.learn - std.concurrent Tid vector initialization problem
- Charles Hixson via Digitalmars-d-learn (14/14) Jun 27 2015 I'm planning an application where a series of threads each need to be
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/20) Jun 27 2015 register(), unregister(), and locate() may be useful:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (23/39) Jun 28 2015 The most elegant solution I can think of is this:
- Charles Hixson (6/34) Jun 30 2015 Thanks. That sounds similar to the approach that I had though
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (3/46) Jul 01 2015 That `shared static this` isn't really necessary here. I
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
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
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
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: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])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.
Jun 30 2015
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:That `shared static this` isn't really necessary here. I originally had an immutable `allTids`, for which it was necessary.On Sunday, 28 June 2015 at 01:02:02 UTC, Charles Hixson wrote: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])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.
Jul 01 2015