Example on how to spawn a thread using a class method?
Ali Çehreli
acehreli at yahoo.com
Mon Jun 17 10:13:37 PDT 2013
On 06/17/2013 03:22 AM, Gary Willoughby wrote:
> Anyone got an example on how to spawn a thread using a class method?
>
> I want to wrap behaviour in a class and launch one of its methods using
> a thread. Once the method is running i want to interact with it from the
> main program by calling other methods which send the thread messages.
>
> I'm stumbling at the first hurdle by not understanding how to use a
> class method to spawn a thread.
>
> Any ideas appreciated.
The address of the member function on a particular class instance is a
delegate. You can pass such a delegate to the thread function. Of
course, 'shared' is important:
import std.stdio;
import std.string;
import std.concurrency;
shared class C
{
int i;
this(int i)
{
this.i = i;
}
string foo(int multiplier) const
{
return format("%s x %s = %s", i, multiplier, i * multiplier);
}
}
// The signature of the delegate matches the member function
void workerWithDelegate(string delegate(int) shared dg)
{
// Receive the argument for the member function
int multiplier = receiveOnly!int();
// Call the member function on the specific object that it is tied to
string result = dg(multiplier);
// (Note: ownerTid is new in 2.063)
ownerTid.send(result);
}
void main()
{
auto c = new shared(C)(42);
// &c.foo makes a delegate that is tied to the specific object 'c'
Tid worker = spawn(&workerWithDelegate, &c.foo);
worker.send(10);
string result = receiveOnly!string();
writefln(`My worker gave me "%s"`, result);
}
However, if you want to tie "calling foo()" on any object, then you must
either wrap that logic in a function (or delegate), conveniently with
the lambda syntax. Here are the minimal changes to the above:
import std.stdio;
import std.string;
import std.concurrency;
shared class C
{
int i;
this(int i)
{
this.i = i;
}
string foo(int multiplier) const
{
return format("%s x %s = %s", i, multiplier, i * multiplier);
}
}
// The signature of the delegate matches the member function. However, it is
// not the direct call to the member function; the lambda will call the
member
// function.
void workerWithDelegate(string function(shared(C), int) dg)
{
// Receive both the object and the argument for the member function
call
auto message = receiveOnly!(shared(C), int)();
shared(C) c = message[0];
int multiplier = message[1];
// Call the member function on the object
string result = dg(c, multiplier);
// (Note: ownerTid is new in 2.063)
ownerTid.send(result);
}
void main()
{
// This lambda knows what member function to call. It will get the
actual
// object at run time.
Tid worker = spawn(&workerWithDelegate,
(shared(C) c, int multiplier) => c.foo(multiplier));
// A new object goes with each message along with the multiplier
worker.send(new shared(C)(42), 10);
string result = receiveOnly!string();
writefln(`My worker gave me "%s"`, result);
}
Ali
More information about the Digitalmars-d-learn
mailing list