digitalmars.D.learn - spawn and wait
- Puming (44/44) Jul 02 2014 Hi,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/31) Jul 02 2014 If you don't care about account for each of them individually,
- Bienlein (3/3) Jul 03 2014 There is also a Semaphore and Barrier class:
- Sean Kelly (6/9) Jul 03 2014 This is probably what I'd do, though both this and thread_joinAll
- Puming (2/35) Jul 03 2014 Thanks that is what I'm looking for
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (22/25) Jul 03 2014 I forgot to mention that if message passing is merely a "workaround" :)
Hi, I want to spawn several similar tasks and then wait for all of them to complete to go on do some other things, like: ```d void task(int id) { // do the stuff } void main() { foreach (i; 0..10) { spawn(&task, i); } wait(?); // wait for all task to complete doSomeOtherThings(); } ``` But I don't see a `wait` method for Tid, similar to Pid in std.process. What is the idiomatic way to do these things? My current workaround is using messages: ```d import std.stdio; import std.concurrency; void child(int id) { writeln("Starting child: ", id); ownerTid.send(id); } void main() { foreach (i; 0..10) { spawn(&child, i); } for (int n = 0; n < 10; ++n) { receive((int i) { writeln("Received:", i); }); } } ``` But it is verbose and seems error prone.
Jul 02 2014
On 07/02/2014 08:29 PM, Puming wrote:I want to spawn several similar tasks and then wait for all of them to complete to go on do some other thingsIf you don't care about account for each of them individually, core.thread.thread_joinAll would work. The following program starts two waves of threads and waits for both of the waves to complete: import std.stdio; import std.concurrency; import core.thread; void foo(Duration duration) { writefln("Working for %s", duration); Thread.sleep(duration); } void spawnThreads(size_t count) { foreach (i; 0 .. count) { spawn(&foo, (i + 1).seconds); } writefln("Started %s workers", count); } void main() { spawnThreads(2); writefln("Waiting for all to finish"); thread_joinAll(); spawnThreads(3); writefln("Waiting for all to finish"); thread_joinAll(); } Ali
Jul 02 2014
There is also a Semaphore and Barrier class: http://dlang.org/phobos/core_sync_barrier.html http://dlang.org/phobos/core_sync_semaphore.html
Jul 03 2014
On Thursday, 3 July 2014 at 10:25:41 UTC, Bienlein wrote:There is also a Semaphore and Barrier class: http://dlang.org/phobos/core_sync_barrier.html http://dlang.org/phobos/core_sync_semaphore.htmlThis is probably what I'd do, though both this and thread_joinAll will only work if you have one kernel thread per spawn. If you're using a fiber-based Scheduler, this won't work as expected. In that case you might want to use spawnLinked and trap the LinkTerminated messages or something like that.
Jul 03 2014
On Thursday, 3 July 2014 at 04:51:07 UTC, Ali Çehreli wrote:On 07/02/2014 08:29 PM, Puming wrote:Thanks that is what I'm looking forI want to spawn several similar tasks and then wait for allof them tocomplete to go on do some other thingsIf you don't care about account for each of them individually, core.thread.thread_joinAll would work. The following program starts two waves of threads and waits for both of the waves to complete: import std.stdio; import std.concurrency; import core.thread; void foo(Duration duration) { writefln("Working for %s", duration); Thread.sleep(duration); } void spawnThreads(size_t count) { foreach (i; 0 .. count) { spawn(&foo, (i + 1).seconds); } writefln("Started %s workers", count); } void main() { spawnThreads(2); writefln("Waiting for all to finish"); thread_joinAll(); spawnThreads(3); writefln("Waiting for all to finish"); thread_joinAll(); } Ali
Jul 03 2014
On 07/02/2014 08:29 PM, Puming wrote:I want to spawn several similar tasks and then wait for all of them to complete to go on do some other things, like:[...]My current workaround is using messages:I forgot to mention that if message passing is merely a "workaround" :) in this case then perhaps std.parallelism is more suitable. For example, your code may be as simple as running a loop in .parallel in a foreach loop. The foreach loop would not advance until all of the parallel tasks have been completed: import std.stdio; import std.parallelism; import std.range; void task(size_t id) { writefln("Working for %s", id); } void main() { foreach (id; iota(10).parallel) { task(id); } writeln("All done"); } Ali
Jul 03 2014