std.concurrency.send

japplegame japplegame at gmail.com
Sat May 19 21:09:49 PDT 2012


> 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; });
>     }
> }
I don't understand. In this way I should call 
startLogger/stopLogger in every application thread because 
loggerTid is thread related and every application thread has its 
own instanse of loggerTid. Instead N+1 threads (N application and 
1 logger) we will get 2*N threads (N application and N loggers). 
Also we should synchronize Logger class because many instances of 
them will run concurrently. This is terrible.
> 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;});
>     }
> }
Intresting idea. I will try it. Thanks.



More information about the Digitalmars-d-learn mailing list