www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Example on how to spawn a thread using a class method?

reply "Gary Willoughby" <dev kalekold.net> writes:
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.
Jun 17 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Jun 17 2013
parent "Gary Willoughby" <dev kalekold.net> writes:
Ah right, so you use a function as a wrapper around the delegate. 
Thanks.
Jun 18 2013