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");
}

Reply via email to