Closure/Stack-to-Heap Semantics
Bruno Medeiros
brunodomedeiros+spam at com.gmail
Fri Oct 3 05:40:13 PDT 2008
dsimcha wrote:
> If I write a loop, and want to submit each iteration of that loop to its own
> thread, or to a thread pool or something, how do I get D to copy the current
> stack frame to the heap each time I use the delegate? For example:
>
> import std.thread, std.stdio, std.c.time;
>
> void main() {
> Thread[] myThreads = new Thread[100];
> foreach(i; 0..100) {
> auto T = new Thread({
> sleep(1); //Give i time to be incremented to 100.
> writeln(i);
> return 0;
> });
> T.start;
> myThreads[i] = T;
> }
> foreach(T; myThreads) {
> T.wait;
> }
> }
>
> This program prints out all 100's because by the time each thread is done
> sleeping, i = 100. How do I make D copy the stack context each time I submit
> a delegate to a thread, in similar fashion to a closure?
Your code is correct and should work as you expect. It doesn't only
because of a bug: http://d.puremagic.com/issues/show_bug.cgi?id=2043
The workaround is to envelop the foreach body in a function, as
explained in the report.
Strangely, you'll run into another bug: writefln is not thread-safe!?
You will have to envelop it with a synchronized statement. So the code
looks like this:
foreach(i; 0..100) {
(int i) {
writeln("(BEGIN) i: ", i, " &i: ", &i);
auto T = new Thread({
sleep(1); //Give i time to be incremented to 100.
synchronized {
writeln("i: ", i, " &i: ", &i);
}
return 0;
});
T.start;
myThreads[i] = T;
} (i);
}
--
Bruno Medeiros - Software Developer, MSc. in CS/E graduate
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
More information about the Digitalmars-d
mailing list