On 08/14/2016 07:44 AM, Charles Hixson via Digitalmars-d-learn wrote:
This is an approach to n x n thread message passing. The idea is that
each thread should be able to pass messages to any other thread. The
only alternative I've come up with involves the main thread handling
each message. Is that a better approach? Is there a better way to
pass lists of Tids?
An attempt using the main thread as a relay follows. I have fewer
doubts about it working, as Tids aren't accessed by multiple threads,
but the logic is more convoluted, and harder to get right.
import std.concurrency;
import std.stdio;
import core.thread;
struct Start { int dummy = 0; }
struct Msg { int orig; int dest; }
struct Done { int dummy = 0; }
enum threadCnt = 3;
void worker (int ndx)
{
writeln ("worker ", ndx, " spawned");
{ auto msg = receiveOnly!(Start)();
writeln ("worker ", ndx, " started");
}
Tid owner = ownerTid;
for (int i = 0; i < threadCnt; i++)
{ if (i != ndx)
{ Msg msg = Msg(ndx, i);
send (owner, msg);
}
}
writeln ("worker ", ndx, " sent msgs");
bool done = false;
while (!done)
{ receive
( (Msg msg) { writeln ("msg from: ", msg.orig, ", to: ",
msg.dest); },
(Done d) { done = true; writeln ("thread ", ndx, " is
done."); }
);
}
send (owner, Done(ndx));
writeln ("worker ", ndx, " is done");
}
void main()
{ Tid[] tidList;
Start start;
Done done;
for (int i = 0; i < threadCnt; i++)
{ tidList ~=spawn (&worker, i);
}
yield;
foreach (i; 0 .. threadCnt) { send (tidList[i], start); }
int tidLength = cast(int)tidList.length;
Thread.sleep (500.msecs);
foreach (i; 0 .. threadCnt) { send (tidList[i], done); }
while (tidLength > 0)
{ receive
( (Msg msg) { send (tidList[msg.dest], msg); },
(Done d) { writeln ("tid ", d.dummy, " is done..",
--tidLength, " remaining."); }
);
}
writeln ("main is done");
}