| 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
Permalink
Reply