Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
July 03, 2014 spawn and wait | ||||
---|---|---|---|---|
| ||||
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 #!/usr/bin/rdmd 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. |
July 03, 2014 Re: spawn and wait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Puming | 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 If 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 |
July 03, 2014 Re: spawn and wait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | There is also a Semaphore and Barrier class: http://dlang.org/phobos/core_sync_barrier.html http://dlang.org/phobos/core_sync_semaphore.html |
July 03, 2014 Re: spawn and wait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Thursday, 3 July 2014 at 04:51:07 UTC, Ali Çehreli wrote:
> 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
>
> If 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
Thanks that is what I'm looking for
|
July 03, 2014 Re: spawn and wait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Puming | 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 |
July 03, 2014 Re: spawn and wait | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bienlein | 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.html
This 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.
|
Copyright © 1999-2021 by the D Language Foundation