Multi-Thread message passing approach

Charles Hixson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 14 11:42:06 PDT 2016


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



More information about the Digitalmars-d-learn mailing list