std.concurrency.send

Nathan M. Swan nathanmswan at gmail.com
Sat May 19 17:46:29 PDT 2012


On Saturday, 19 May 2012 at 21:13:14 UTC, japplegame wrote:
>> You don't need to mark Tids as shared.
> Okay. I'm writting logger. Logger is global object and it is
> running in its own separate thread (for example, writting logs 
> to
> remote database).
> My application has several threads and all of them want to log
> something. How to share this global logger between threads? I
> think the simplest way is to share logger's thread tid and other
> thread can send logs via this shared tid.

public:
void startLogger(LogConstructorArgs args) {
     loggerTid = spawn(&loggerThread, args);
}

void log(string msg, OtherOptions oo) {
     loggerTid.send(LogMsg(msg, oo));
}

void stopLogger() {
     loggerTid.send(QuitMsg());
}

private:
Tid loggerTid;

struct LogMsg {
     string msg;
     OtherOptions oo;
}

struct QuitMsg {}

void loggerThread(LogConstructorArgs args) {
     Logger lg = new Logger(args);
     bool cont = true;
     while(cont) {
         receive((LogMsg lm) { lg.log(lm.msg, lm.oo); },
                 (QuitMsg qm) { cont = false; });
     }
}

>> If you originally create it as shared, you don't need to do 
>> the casting.
> Yes. I don't need to cast to shared, but inside thread I get
> shared object and can't store/call/pass it without casting away
> that shared attribute. Or I should make shared everyting that
> have deal with shared object.
> I'am trying to follow Safe D concept, but it forbids casting 
> away
> shared.

If you are passing objects between threads, make it shared. This 
might seem annoying, but in general you should try to shift your 
thinking into having thread-local objects and communicating via 
structs.

But when you use global/singleton objects (any case where there's 
one instance of the class), convert it into a thread, FROM

class <name> {
     this(<cons args>) {
         <constructor>
     }

     void <method1>() {
         // ...
     }

     int <method2>() {
         int result;
         // ...
         return result;
     }

     <private fields> // you encapsulate and have no public 
fields, right?
}

TO

void <name>Thread(<cons args>) {
     <private fields>
     <constructor>
     bool cont = true;
     while(cont) {
         receive(
             (<method1>Msg) {
                 // ...
             },
             (Tid r, <method2>Msg) {
                 int result;
                 // ...
                 r.send(<method2>ReturnMsg(result));
             }
             (QuitMsg qm) {cont = false;});
     }
}



More information about the Digitalmars-d-learn mailing list