Thread overview
Possible to pass a member function to spawn?
Feb 06, 2012
Oliver Puerto
Feb 07, 2012
James Miller
February 06, 2012
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
February 07, 2012
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
February 07, 2012
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 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
February 07, 2012
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