February 10, 2012 Bug? taskPool.map() with bufSize and writeln() gets stuck | ||||
---|---|---|---|---|
| ||||
Ubuntu 11.10 64-bit dmd. The following program gets stuck during the writeln() call. - The foo() call alone works fine. - The program works fine when there is no writeln() call nor foo() call. All elements get processed in that case and the results are ignored. Am I using taskPool.map incorrectly or is this a bug? import std.stdio; import std.parallelism; import core.thread; int func(int i) { writeln("processing ", i); return i; } void main() { auto results = taskPool.map!func([1,2,3,4,5,6,7,8], 2); writeln(results); // <-- Gets stuck foo(results); // this works fine } void foo(R)(R range) { for ( ; !range.empty; range.popFront()) { writeln(range.front); } } Thank you, Ali |
February 11, 2012 Re: Bug? taskPool.map() with bufSize and writeln() gets stuck | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 02/10/2012 10:28 AM, Ali Çehreli wrote: > Ubuntu 11.10 64-bit dmd. > > The following program gets stuck during the writeln() call. > > - The foo() call alone works fine. > > - The program works fine when there is no writeln() call nor foo() call. > All elements get processed in that case and the results are ignored. > > Am I using taskPool.map incorrectly or is this a bug? > > import std.stdio; > import std.parallelism; > import core.thread; > > int func(int i) > { > writeln("processing ", i); > return i; > } > > void main() > { > auto results = taskPool.map!func([1,2,3,4,5,6,7,8], 2); > > writeln(results); // <-- Gets stuck > > foo(results); // this works fine > } > > void foo(R)(R range) > { > for ( ; !range.empty; range.popFront()) { > writeln(range.front); > } > } > > Thank you, > Ali I have asked the same question on the main D newsgroup. It turns out, since the writeln() calls in func() and main() share the same resource (namely stdout), the main thread and the task threads get dead-locked on an output synchronization lock. Changing the call in main to be on stderr fixes the issue and I get what I want. Now I can see how taskPool.map works semi-lazily: import std.stdio; import std.parallelism; import core.thread; int func(int i) { writeln("processing ", i); Thread.sleep(dur!"seconds"(1)); return i; } void main() { auto results = taskPool.map!func([1,2,3,4,5,6,7,8], 2); stderr.writeln(results); // <-- now on stderr } The output: processing 1 processing 2 [1, 2processing 3 processing 4 , 3, 4processing 5 processing 6 , 5, 6processing 7 processing 8 , 7, 8] std.parallelism is only for when the tasks are truly independent from each other. I had forgotten that using stdout would violate that condition. Ali |
Copyright © 1999-2021 by the D Language Foundation