July 22, 2011 can I force a parallel foreach to finish? | ||||
---|---|---|---|---|
| ||||
Hi, all. So I'm getting the classic "concurrency noob" behavior from this code: shared int times; int[] iterationRange = new int[2500]; foreach (pos, ref i; parallel(iterationRange)){ times++; } writeln(times); } Prints random numbers near 1,000. Looking at the documentation for std.concurrency, it appears that when dealing with tasks, you have to yieldForce to get them to finish. Is there a method that blocks until taskPool itself is empty? I think the problem is not concurrent modification, the foreach just seems to return too early, as seen here: int times; void shareAugmenter(){ bool cont = true; while(cont){ receive( (int i){times++;}, (string s){writefln("in the thread %s",times);cont = false;}); } } void main(string[] args){ auto td = spawn(&shareAugmenter); int[] iterationRange = new int[2500]; foreach (pos, ref i; parallel(iterationRange)){ td.send(1); } writeln(times); td.send(""); writeln(times); prints 0 0 In the thread 2500 Cheers, Charles. |
July 25, 2011 Re: can I force a parallel foreach to finish? | ||||
---|---|---|---|---|
| ||||
Posted in reply to McAnany, Charles E | On Fri, 22 Jul 2011 18:38:15 -0400, McAnany, Charles E <mcanance@rose-hulman.edu> wrote: > Hi, all. So I'm getting the classic "concurrency noob" behavior from this code: > shared int times; > int[] iterationRange = new int[2500]; > foreach (pos, ref i; parallel(iterationRange)){ > times++; > } > writeln(times); > } > Prints random numbers near 1,000. > Looking at the documentation for std.concurrency, it appears that when dealing with tasks, you have to yieldForce to get them to finish. Is there a method that blocks until taskPool itself is empty? I think you are misreading something, std.concurrency does not have to do with std.parallelism Note that while compiler inserts memory barriers around operations on shared data, it does not get rid of race issues. That is, times++ is *not* atomic, so you cannot expect it to avoid races. Try: import core.atomic; atomicOp!"+="(times, 1); > I think the problem is not concurrent modification, the foreach just seems to return too early, as seen here: > > int times; > void shareAugmenter(){ > bool cont = true; > while(cont){ > receive( (int i){times++;}, > (string s){writefln("in the thread %s",times);cont = false;}); > } > } > void main(string[] args){ > auto td = spawn(&shareAugmenter); > int[] iterationRange = new int[2500]; > foreach (pos, ref i; parallel(iterationRange)){ > td.send(1); > } > writeln(times); > td.send(""); > writeln(times); > prints > 0 > 0 > In the thread 2500 Note that int times is THREAD LOCAL, so essentially you have created two separate copies of times, one in the main thread and one in the sub thread. Change the declaration to: shared int times; -Steve |
Copyright © 1999-2021 by the D Language Foundation