Closure/Stack-to-Heap Semantics

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Sep 25 02:04:05 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:
> 
[snip]
> 
> 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?

The only way I know of to get D (presumably v2.x) to copy the stack 
frame to the heap is to create a delegate using it that would otherwise 
outlast the stack frame in question. Only one such copy is made per 
stack frame, however; the solution is therefore to create a separate 
stack frame per iteration through the loop:
-----
import std.thread, std.stdio, std.c.time;

int delegate() threadfn(int i) {
     return {
             sleep(1);  //Give i time to be incremented to 100.
             writeln(i);
             return 0;
         };
}

void main() {
     Thread[] myThreads = new Thread[100];
     foreach(i; 0..100) {
         auto T = new Thread(threadfn(i));
         T.start;
         myThreads[i] = T;
     }
     foreach(T; myThreads) {
         T.wait;
     }
}
-----
If you need to access other variables from main() in the threads, either 
pass a copy (or pointer) to threadfn(), or change threadfn() into a 
nested function in main. Remember though: any variable not accessed as a 
copy on threadfn's stackframe will be shared between all the threads.



More information about the Digitalmars-d mailing list