digitalmars.D - Thread questions
- novice (10/10) Oct 06 2004 Hello everybody.
- Ben Hinkle (6/18) Oct 07 2004 Why do you want to obtain the thread return value? Usually you just retu...
- novice (3/5) Oct 07 2004 :)
- Ben Hinkle (60/63) Oct 07 2004 Be aware that thre return value for a thread is the pass/fail status fla...
- Ben Hinkle (4/31) Oct 07 2004 I should add that in this example the ReentantLock can also be replaced ...
- Ben Hinkle (9/36) Oct 09 2004 After a bit more experimenting it seems like a volatile in place of
- Burton Radons (47/54) Oct 07 2004 You might want to use an asynchronous return structure for that, such as...
- Sjoerd van Leent (9/78) Oct 07 2004 Looks good. I would mention one thin, declare AsynchronousReturn as
- Sean Kelly (6/11) Oct 07 2004 Since we're being picky, make the updates of finished and value atomic. ...
- Sjoerd van Leent (4/22) Oct 07 2004 I just had a bad day...
Hello everybody. Q1: Class Thread in std.thread.d has constructor this(int (*fp)(void *), void *arg), i.e. (if i understand) thread function must return int value. But i can't find, how obtain this value. I found Windows API GetExitCodeThread. But, may be, Thread class have ability to get the value, returned by thread function? Q2: For what we have run() method of Thread class? Thanks!
Oct 06 2004
novice wrote:Hello everybody. Q1: Class Thread in std.thread.d has constructor this(int (*fp)(void *), void *arg), i.e. (if i understand) thread function must return int value. But i can't find, how obtain this value. I found Windows API GetExitCodeThread. But, may be, Thread class have ability to get the value, returned by thread function?Why do you want to obtain the thread return value? Usually you just return 0 at the end of fp() to mean "the thread ended normally".Q2: For what we have run() method of Thread class?It seems strange I guess but run() will immediately run the thread callback in the current thread instead of starting a new thread. I suppose it is handy if you change you mind before actually starting the other thread.Thanks!
Oct 07 2004
Thank you, Ben Hinkle.Why do you want to obtain the thread return value?I need to pass some results of child thread's to parent (main) thread.handy if you change you mind before actually starting the other thread.:)
Oct 07 2004
"novice" <novice_member pathlink.com> wrote in message news:ck3g33$1em3$1 digitaldaemon.com...Thank you, Ben Hinkle.Be aware that thre return value for a thread is the pass/fail status flag and shouldn't be used to return the result of some computation. If you want to communicate the result of a computation I'd use a shared resource and pass that to the thread. For example import std.thread; int main() { int *res; res = new int; Thread t = new Thread(function int(void*vptr) { int*res = cast(int*)vptr; *res = 100*100; // your code here return 0; },res); t.start(); //... do something until thread finishes printf("%d\n",*res); return 0; } Or you can use delegates and reference the stack of the calling thread directly (as long as the calling function doesn't return while the child thread is running). You might want to check out the Locks library for some handy threading functions. For more info see http://home.comcast.net/~benhinkle/mintl/locks.html. With dmd-102 I've been getting some pretty strange behaviors so please report bugs to me. I typically get fewer bugs with the library compiled without -O or unittests. Here is a test program that uses CountDownLatches to coordinate threads and a ReentrantLock to control access to a counter. import locks.all; import std.thread; int main() { CountDownLatch go = new CountDownLatch(1); CountDownLatch allDone = new CountDownLatch(4); Thread[4] t; int total; ReentrantLock lock = new ReentrantLock; for (int i=0; i < 4; i++) { t[i] = new Thread( delegate int() { go.wait(); // wait for signal from main thread // ... do something interesting ... lock.lock(); total += 100; for(int k=0;k<1000000;k++) { } // seems to need a pause? lock.unlock(); allDone.countDown(); return 0; }); t[i].start(); } go.countDown(); // let worker threads go allDone.wait(); // wait for all workers to finish printf("%d\n",total); // total should now be 400 return 0; } But back to your original question, I don't know how to get the return value after the thread is done. -BenWhy do you want to obtain the thread return value?I need to pass some results of child thread's to parent (main) thread.
Oct 07 2004
import locks.all; import std.thread; int main() { CountDownLatch go = new CountDownLatch(1); CountDownLatch allDone = new CountDownLatch(4); Thread[4] t; int total; ReentrantLock lock = new ReentrantLock; for (int i=0; i < 4; i++) { t[i] = new Thread( delegate int() { go.wait(); // wait for signal from main thread // ... do something interesting ... lock.lock(); total += 100; for(int k=0;k<1000000;k++) { } // seems to need a pause? lock.unlock(); allDone.countDown(); return 0; }); t[i].start(); } go.countDown(); // let worker threads go allDone.wait(); // wait for all workers to finish printf("%d\n",total); // total should now be 400 return 0; }I should add that in this example the ReentantLock can also be replaced with synchronized { total += 100; }
Oct 07 2004
import locks.all; import std.thread; int main() { CountDownLatch go = new CountDownLatch(1); CountDownLatch allDone = new CountDownLatch(4); Thread[4] t; int total; ReentrantLock lock = new ReentrantLock; for (int i=0; i < 4; i++) { t[i] = new Thread( delegate int() { go.wait(); // wait for signal from main thread // ... do something interesting ... lock.lock(); total += 100; for(int k=0;k<1000000;k++) { } // seems to need a pause? lock.unlock(); allDone.countDown(); return 0; }); t[i].start(); } go.countDown(); // let worker threads go allDone.wait(); // wait for all workers to finish printf("%d\n",total); // total should now be 400 return 0; }After a bit more experimenting it seems like a volatile in place of the for loop will also make it work lock.lock(); total += 100; volatile lock.unlock(); Without the loop or volatile I get seg-v's on the unlock. Probably the loop was just preventing some reordering optimization. I haven't looked at the disassembly to see exactly what happened. -Ben
Oct 09 2004
novice wrote:Thank you, Ben Hinkle.You might want to use an asynchronous return structure for that, such as this: import std.thread; struct AsynchronousReturn (ReturnType) { bit finished; /**< Set to true when execution has finished. */ ReturnType value; /**< Return value. */ ReturnType delegate () func; /**< The function being executed. */ /** Execute the function, assign value, and set finished to true. */ int run () { value = func (); finished = true; return 0; } /** Execute the function in another thread, assign value, and set finished once done. */ void execute (ReturnType delegate () func) { finished = false; this.func = func; (new Thread (&run)).start (); } } void test () { AsynchronousReturn! (int) async; async.execute (delegate int () { int length; for (int c; c < 10; c ++) { length += printf ("flah %d\n", c); Thread.yield (); } return length; }); while (!async.finished) { printf ("waiting...\n"); Thread.yield (); } printf ("returned %d!\n", async.value); } Then you can return whatever you want.Why do you want to obtain the thread return value?I need to pass some results of child thread's to parent (main) thread.
Oct 07 2004
Burton Radons wrote:novice wrote:Looks good. I would mention one thin, declare AsynchronousReturn as class (such that it can be send to other functions) and declare finished and value as private and add two routines that get the value, else one could break the functionality by setting the finished state to whatever someone wants (the same goes for value). For the rest, nice work (Well I think it is nice work ;-) ) Regards, SjoerdThank you, Ben Hinkle.You might want to use an asynchronous return structure for that, such as this: import std.thread; struct AsynchronousReturn (ReturnType) { bit finished; /**< Set to true when execution has finished. */ ReturnType value; /**< Return value. */ ReturnType delegate () func; /**< The function being executed. */ /** Execute the function, assign value, and set finished to true. */ int run () { value = func (); finished = true; return 0; } /** Execute the function in another thread, assign value, and set finished once done. */ void execute (ReturnType delegate () func) { finished = false; this.func = func; (new Thread (&run)).start (); } } void test () { AsynchronousReturn! (int) async; async.execute (delegate int () { int length; for (int c; c < 10; c ++) { length += printf ("flah %d\n", c); Thread.yield (); } return length; }); while (!async.finished) { printf ("waiting...\n"); Thread.yield (); } printf ("returned %d!\n", async.value); } Then you can return whatever you want.Why do you want to obtain the thread return value?I need to pass some results of child thread's to parent (main) thread.
Oct 07 2004
In article <ck3ump$1rnr$1 digitaldaemon.com>, Sjoerd van Leent says...Looks good. I would mention one thin, declare AsynchronousReturn as class (such that it can be send to other functions) and declare finished and value as private and add two routines that get the value, else one could break the functionality by setting the finished state to whatever someone wants (the same goes for value).Since we're being picky, make the updates of finished and value atomic. You could probably use CompareAndSwap from MinTL. This should take care of memory visibility. The alternate would be to wrap the reads and writes in a synchronized block. Sean
Oct 07 2004
Sean Kelly wrote:In article <ck3ump$1rnr$1 digitaldaemon.com>, Sjoerd van Leent says...I just had a bad day... Regards, SjoerdLooks good. I would mention one thin, declare AsynchronousReturn as class (such that it can be send to other functions) and declare finished and value as private and add two routines that get the value, else one could break the functionality by setting the finished state to whatever someone wants (the same goes for value).Since we're being picky, make the updates of finished and value atomic. You could probably use CompareAndSwap from MinTL. This should take care of memory visibility. The alternate would be to wrap the reads and writes in a synchronized block. Sean
Oct 07 2004