www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How are theads, Tid and spawn related?

reply "Neven" <neven.miculinic+d gmail.com> writes:
Ok, a newbie question ahead. I want to create new thread which 
calls given function with some parameters. Thus, I think spawn is 
the right function for me. However that functions returns Tid and 
not a Thread object.

So I want to know how can I make a Thread object out of it. What 
I would like to achieve is to wait for spawned thread to finish 
its execution, that is join with main thread.
Nov 01 2014
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/01/2014 04:32 PM, Neven wrote:
 Ok, a newbie question ahead. I want to create new thread which calls
 given function with some parameters. Thus, I think spawn is the right
 function for me. However that functions returns Tid and not a Thread
 object.

 So I want to know how can I make a Thread object out of it. What I would
 like to achieve is to wait for spawned thread to finish its execution,
 that is join with main thread.
You don't need a Thread object to wait for a thread to finish. One option is to wait for a specific message: import std.concurrency; struct Done {} void func(int i) { ownerTid.send(Done()); } void main() { spawn(&func, 42); receiveOnly!Done(); // <-- Waiting for the Done message } Another option is to wait for all child threads by thread_joinAll(): import core.thread; // ... thread_joinAll(); The reason I suggest the above is because I don't know the answer to your question. :) Ali
Nov 01 2014
prev sibling next sibling parent reply "Sean Kelly" <sean invisibleduck.org> writes:
Note that thread_joinAll is called automatically when main exits, 
so if you just want to be sure that your spawned thread completes 
you don't have to do anything at all.

The decision to obscure the Thread object in std.concurrency was 
deliberate, as it allows us to use more than just kernel threads 
for concurrency. The thread may even live in another process and 
the message sent via IPC. If you want to start an asynchronous 
task and wait for it to complete I suggest the method Ali 
outlines above. You can also create a Thread directly. What we 
should really have for this sort of thing is futures, but they 
don't exist yet. std.parallelism might be worth a look as well, 
since it has a task queue.
Nov 01 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/01/2014 11:13 PM, Sean Kelly wrote:

 Note that thread_joinAll is called automatically when main exits
Has that always been the case? I remember having to inject thread_joinAll() calls at the ends of the main()s of a couple of examples because of having trouble otherwise. Can I safely remove thread_joinAll()s if they are the last lines in main()? Ali
Nov 01 2014
parent reply "Sean Kelly" <sean invisibleduck.org> writes:
On Sunday, 2 November 2014 at 06:23:38 UTC, Ali Çehreli wrote:
 On 11/01/2014 11:13 PM, Sean Kelly wrote:

 Note that thread_joinAll is called automatically when main
exits Has that always been the case? I remember having to inject thread_joinAll() calls at the ends of the main()s of a couple of examples because of having trouble otherwise. Can I safely remove thread_joinAll()s if they are the last lines in main()?
It has always been the case. In fact, I have a comment in the body of Thread.start() explaining this potential race and explaining the need for certain operations in that function. So if there is a race, it isn't meant to be here and should be fixed. I also just filed: https://issues.dlang.org/show_bug.cgi?id=13672 so some attention needs to be paid to this function anyway.
Nov 02 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/02/2014 09:04 AM, Sean Kelly wrote:

 On Sunday, 2 November 2014 at 06:23:38 UTC, Ali Çehreli wrote:
 Can I safely remove thread_joinAll()s if they are the last lines in
 main()?
It has always been the case. In fact, I have a comment in the body of Thread.start() explaining this potential race and explaining the need for certain operations in that function.
I've grepped for thread_joinAll calls in my examples and identified two cases where I needed it at the end of main, both of which about the need to "pull" thread_joinAll inside main's scope. Otherwise, the automatic thread_joinAll call would happen after main's scope ends and it would be too late in the following cases. 1) A scope(exit) should not unregister() before all threads finish. 2) A thread still uses an object tied to main's scope. void main() { auto first = spawn(&player, "second"); register("first", first); scope(exit) unregister("first"); // <-- (1) // ... immutable(int) i = 42; spawn(&worker, &i); // <-- (2) // ... thread_joinAll(); // <-- justified } The thread_joinAll() at the end of main() above is justified to take care of both of those cases. Ali
Nov 02 2014
parent "Sean Kelly" <sean invisibleduck.org> writes:
For those cases you could use spawnLinked and then receive 
LinkTerminated as well, if you're looking for a solution within 
the concurrency API.
Nov 02 2014
prev sibling next sibling parent "Sean Kelly" <sean invisibleduck.org> writes:
Note that thread_joinAll is called automatically when main exits,
so if you just want to be sure that your spawned thread completes
you don't have to do anything at all.

The decision to obscure the Thread object in std.concurrency was
deliberate, as it allows us to use more than just kernel threads
for concurrency. The thread may even live in another process and
the message sent via IPC. If you want to start an asynchronous
task and wait for it to complete I suggest the method Ali
outlines above. You can also create a Thread directly. What we
should really have for this sort of thing is futures, but they
don't exist yet. std.parallelism might be worth a look as well,
since it has a task queue.
Nov 01 2014
prev sibling parent Russel Winder via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Sat, 2014-11-01 at 23:32 +0000, Neven via Digitalmars-d-learn wrote:
 Ok, a newbie question ahead. I want to create new thread which=20
 calls given function with some parameters. Thus, I think spawn is=20
 the right function for me. However that functions returns Tid and=20
 not a Thread object.
=20
 So I want to know how can I make a Thread object out of it. What=20
 I would like to achieve is to wait for spawned thread to finish=20
 its execution, that is join with main thread.
Modern thinking is that threads are managed infrastructure that application code should never manage explicitly. In this way of thinking application code only cares about data readiness and/or message passing. With this mind set, using D, you spawn a task and get a Tid in response. The Tid allows you to send messages to the asynchronous activity and to receive messages from it. This is all very, very close to actors. Underneath the actors, there are threads, but your code doesn't care, they are managed resource. All you code cares about is sending messages between asynchronous tasks. As an example of spawning a function and waiting for it to complete using spawn you might look at:=20 https://github.com/russel/Pi_Quadrature/blob/master/D/pi_spawn.d --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Nov 02 2014