View mode: basic / threaded / horizontal-split · Log in · Help
February 06, 2012
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
February 07, 2012
Re: Possible to pass a member function to spawn?
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
Re: Possible to pass a member function to spawn?
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
Re: Possible to pass a member function to spawn?
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
Top | Discussion index | About this forum | D home