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