www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Possible to pass a member function to spawn?

reply "Oliver Puerto" <saxo123 gmx.de> writes:
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
Feb 06 2012
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 06 Feb 2012 16:38:03 -0500, Oliver Puerto <saxo123 gmx.de> wrote:

 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.

Welcome to D! Unfortunately, it looks like functions are the only runnable types via spawn. There should technically be a delegate version, and then you would be able to do: auto tid = spawn(&myActor.run); which would run the run() method of myActor in a separate thread. I'm not sure what the technical limitation, but I think it has to do with guarantees that no unshared data is passed (I don't believe it was possible to detect a shared delegate vs. a non-shared one, that may have changed). For now, your method of using spawn is correct. You should note that the current implementation is not quite finished, and some pieces of TDPL will not work yet. We are getting there, though! Also, for future reference, the newsgroup digitalmars.D.learn is more appropriate for these types of questions. -Steve
Feb 06 2012
prev sibling next sibling parent James Miller <james aatch.net> writes:
It is also worth noting that the reason delegates are not eligible for
thread spawn is that delegates hold references from outside their
definition. This means that delegates can hold references to data that
outside their thread, thus breaking the rule that all data is
thread-local unless specified otherwise.

The compiler could try to reason about your program and figure out
that your "delegate" doesn't actually access cross-thread data, but
that is very, very hard to prove. D's design is not suited to the
Actor model, at least not without some modification.

On 7 February 2012 13:16, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 On Mon, 06 Feb 2012 16:38:03 -0500, Oliver Puerto <saxo123 gmx.de> wrote:

 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 kn=


 ... 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=


 best, I would like to do something like this:

 =C2=A0 =C2=A0MyActor myActor =3D new MyActor();
 =C2=A0 =C2=A0auto tid =3D spawn(&start, &myActor.run());

 However, this doesn't work. So I came up with the solution below where t=


 start function is called with myActor as an argument.

Welcome to D! Unfortunately, it looks like functions are the only runnable types via spawn. =C2=A0There should technically be a delegate version, and then you=

 be able to do:

 auto tid =3D spawn(&myActor.run);

 which would run the run() method of myActor in a separate thread. =C2=A0I=

 sure what the technical limitation, but I think it has to do with guarant=

 that no unshared data is passed (I don't believe it was possible to detec=

 shared delegate vs. a non-shared one, that may have changed).

 For now, your method of using spawn is correct.

 You should note that the current implementation is not quite finished, an=

 some pieces of TDPL will not work yet. =C2=A0We are getting there, though=

 Also, for future reference, the newsgroup digitalmars.D.learn is more
 appropriate for these types of questions.

 -Steve

Feb 06 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 06 Feb 2012 21:26:02 -0500, James Miller <james aatch.net> wrote:

 It is also worth noting that the reason delegates are not eligible for
 thread spawn is that delegates hold references from outside their
 definition. This means that delegates can hold references to data that
 outside their thread, thus breaking the rule that all data is
 thread-local unless specified otherwise.

 The compiler could try to reason about your program and figure out
 that your "delegate" doesn't actually access cross-thread data, but
 that is very, very hard to prove. D's design is not suited to the
 Actor model, at least not without some modification.

He wants to do a delegate of a method from a shared class, there is no unknown context here. I agree delegate literals should not be eligible. Then again, those delegates should not be marked shared. When I tried to run a simple test, the compiler reported: Error: template std.concurrency.spawn(T...) cannot deduce template function from argument types !()(void delegate() shared) So clearly, the compiler knows that the delegate is from a shared object. This should be doable today... -Steve
Feb 06 2012