Possible to pass a member function to spawn?

Oliver Puerto saxo123 at gmx.de
Wed Feb 8 00:13:22 PST 2012


Hi guys,

thanks for all the answers to my post. In the meanwhile I have continued playing around with my little actor "project". See below what I came up with. Actually, I like this semi object-oriented approach I found. In the beginning a spawn is done with a pointer to the dispatch function. This is still the non-OOP approach. Here, things remain as intended by the language designers in the way that threads already have a message queue and already are some kind of actor at the same time. After the spawn things become object-oriented as every message send results in a method in the actor class to be invoked. So far I'm quite happy with this.

In the main clause below I do several times a Thread.sleep. Whenever the Thread.sleep is called the actor responds to the previously sent message(s). Without the Thread.sleep they just sit in the actor and don't get executed (no expected output on the console). This is still some mystery to me...

Regards, Oliver

int main()
{
    MyActor myActor = new MyActor();

    auto tid = myActor.start(thisTid);

    tid.send(123);    
    tid.send(456);    
    tid.send(1.0f);

    Thread.sleep(dur!("seconds")( 1 ));

    tid.send("hello");
    Thread.sleep(dur!("seconds")( 1 ));

    tid.send(thisTid, "shutdown");

    receive( 
        (int x) { writeln("actor has shut down with return code: ", x); 
    });

    writeln("end");

    return 0;
}

----------------- AbstractActor.d -----------------

shared abstract class AbstractActor {    

    public static string SHUTDOWN = "shutdown";

    protected bool cont = true;

    Tid start(Tid ownerTid) {
        return spawn(&dispatch, this);
    }

    void run() {
        while(cont) {
            act();
        }
    }

    abstract void act();

    protected bool checkShutdown(Tid sender, string msg) {
        if(msg == SHUTDOWN) {
            writeln("shutting down ...");
            cont = false;
            sender.send(0);
            return true;
        }
        return false;
    }

}

void dispatch(AbstractActor actor)
{
    actor.run();
}

----------------- AbstractActor.d -----------------


shared class MyActor : AbstractActor {    

    void run(int i) {
        writeln(i);
    }

    void act() 
    {
        receive(
            (int msg) { run(msg); },
            (Tid sender, string msg) { checkShutdown(sender, msg); },
            (Variant v) { writeln("huh?"); }            
        );
    }

}


-------- Original-Nachricht --------
> Datum: Mon, 06 Feb 2012 22:38:03 +0100
> Von: "Oliver Puerto" <saxo123 at gmx.de>
> An: digitalmars-d at puremagic.com
> Betreff: Possible to pass a member function to spawn?

> Hello,
> 
> I'm very new to D. Just started reading "The D programming language". I
> should read it from beginning to end before posting questions here. I know
> ... But I'm just too impatient. The issue seems not to be that simple,
> nevertheless. The code below compiles with Visual Studio.
> 
> I want to have something like my actor class that I can start running in
> it's own thread like in Scala or other languages that support actors. So at
> best, I would like to do something like this:
> 
>     MyActor myActor = new MyActor();
>     auto tid = spawn(&start, &myActor.run());
> 
> However, this doesn't work. So I came up with the solution below where the
> start function is called with myActor as an argument. The code at the end
> of the mail prints this to the console:
> 
> MyActor 123
> tid
> Main thread received message: -1
> 
> This solution works, but is really not very elegant. I'm not sure whether
> declaring MyActor shared is a good solution. The minimum I would like to
> achieve is to have the start function in the source file with the MyActor
> class. Also this does not compile. I played with delegates but couldn't get it
> to compile.
> 
> I'd be thankful for any useful suggestions or hints.
> 
> Regards, Oliver Plow
> 
> -------------------- beginning of main.d -------------- 
> 
> import MyActor;
> 
> int main()
> {
> 
>     MyActor myActor = new MyActor();
>     auto tid = spawn(&start, myActor); 
> 
>     tid.send(123);
>     tid.send(thisTid);
> 
>     receive( 
>        (int x) {
>         writeln("Main thread received message: ", x);
>        });
> 
>     return 0;
> }
> 
> 
> void start(MyActor actor)
> {
>     bool cont = true;
> 
>     while (cont)
>     {
>         receive( 
>             (int msg) { actor.run(msg); },
>             (Tid sender) { cont = false; sender.send(-1); },
> 	    (Variant v) { writeln("huh?"); } 
> 	);
>     }
> }
> 
> -------------------- end of main.d -------------- 
> 
> 
> -------------------- beginning of MyActor.d -------------- 
> 
> shared class MyActor {
> 
>     void run(int i) {
>         write("MyActor ");
> 	write(i);
> 	write("\n");
>     }
> 
> }
> 
> -------------------- end of MyActor.d --------------
> 
> 
> -- 
> Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
> belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de

-- 
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de


More information about the Digitalmars-d mailing list