Stopping and restart shreds

I'd like to use functions to stop and restart shreds. Is this the right way to do it? It doesn't seem to be working properly - I get errors from some shreds when I thought they'd all stopped. Shred shredA, shredB; fun void sporkAll() { spork ~ funA() @=> shredA; spork ~ funB() @=> shredB; me.yield(); } fun void killAllShreds() { shredA.exit(); shredB.exit(); me.yield(); } Ollie

I'd like to use functions to stop and restart shreds. Is this the right way to do it? It doesn't seem to be working properly - I get errors from some shreds when I thought they'd all stopped.
Shred shredA, shredB;
fun void sporkAll() { spork ~ funA() @=> shredA; spork ~ funB() @=> shredB; me.yield(); }
fun void killAllShreds() { shredA.exit(); shredB.exit(); me.yield(); }
In previous versions of chuck invoking 'exit' on shred didn't seem to work (for me). Instead I was killing shreds in this way: shredA.id => machine.remove; But in 1.2.0.6 'exit' seems to work properly. Another significant note: the shred which is calling these functions must not exit. Otherwise those functions won't work for some reason. Developers, please correct me if I'm wrong :) ___________________ w31rd0

On 7/24/06, w31rd0
Another significant note: the shred which is calling these functions must not exit. Otherwise those functions won't work for some reason.
Developers, please correct me if I'm wrong :)
I think that might be related to a bug I ran into a while back. I'd have a shred report that it was going to exit (using <<<....>>> ), then exit. This would result in a shred that would be gone but no comment on the schreen. Having some small amount of time pass inbetween would fix this. Could be the same issue; I'm not at home or near a chuck-ing computer but try a simple 1::ms => now; inbetween those lines and see wether it works. Ugly but maybe a work-around for now? Hope that helps, Kas.

On 7/24/06, w31rd0
wrote: Another significant note: the shred which is calling these functions must not exit. Otherwise those functions won't work for some reason.
Developers, please correct me if I'm wrong :)
I think that might be related to a bug I ran into a while back. I'd have a shred report that it was going to exit (using <<<....>>> ), then exit. This would result in a shred that would be gone but no comment on the schreen. Having some small amount of time pass inbetween would fix this.
Could be the same issue; I'm not at home or near a chuck-ing computer but try a simple 1::ms => now; inbetween those lines and see wether it works. Ugly but maybe a work-around for now?
Currently in ChucK, a parent shred will terminate any child shreds when the parent terminates. For example: --- // start fun void foo() { <<< "foo!!!" >>>; } // spork foo spork ~ foo(); // end of program --- In this case, "foo" will NOT print because the parent shred has exited before the child has a chance to run. As Kassen mentioned, advancing time in the parent shred will allow children to execute. If no time advance is desired, me.yield() should work. --- // start fun void foo() { <<< "foo!!!" >>>; } // spork foo spork ~ foo(); // yield to let foo run, no time advance me.yield(); // end of program --- Hope this helps. Ge!

Currently in ChucK, a parent shred will terminate any child shreds when the parent terminates. For example:
--- // start fun void foo() { <<< "foo!!!" >>>; }
// spork foo spork ~ foo();
// end of program ---
In this case, "foo" will NOT print because the parent shred has exited before the child has a chance to run. As Kassen mentioned, advancing time in the parent shred will allow children to execute. If no time advance is desired, me.yield() should work.
--- // start fun void foo() { <<< "foo!!!" >>>; }
// spork foo spork ~ foo();
// yield to let foo run, no time advance me.yield();
// end of program ---
Hope this helps.
Yep. Unless foo() is doing something non-trivial. For example, dur T1; dur T2; fun void foo() { T1 => now; <<< "foo!!!" >>>; } // spork foo spork ~ foo(); T2 => now; In this case "foo" will print only if T2 > T1. ___________________ w31rd0

Ge Wang wrote:
Currently in ChucK, a parent shred will terminate any child shreds when the parent terminates.
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business. I have a lot of examples in my code on me explicitly having to handle this and it both 1) looks ugly and 2) is not that robust. BTW: would it be possible to grab the id of the child and wait for that is to finish, instead of my current way (chucking a sufficiently large dur to now in the parent after sporking)? -- peace, love & harmony Atte http://www.atte.dk | quartet: http://www.anagrammer.dk http://www.atte.dk/gps | compositions: http://www.atte.dk/compositions

Currently in ChucK, a parent shred will terminate any child shreds when the parent terminates.
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
I have a lot of examples in my code on me explicitly having to handle this and it both 1) looks ugly and 2) is not that robust.
BTW: would it be possible to grab the id of the child and wait for that is to finish, instead of my current way (chucking a sufficiently large dur to now in the parent after sporking)?
You can make your children explicitly signal they are exiting, like this: fun void foo( Event e ) { 10::ms => now; <<< "foo", "" >>>; e.signal(); } fun void bar( Event e ) { 1000::ms => now; <<< "bar", "" >>>; e.signal(); } Event e1, e2; spork ~ foo( e1 ); spork ~ bar( e2 ); e1 => now; e2 => now; Still ugly though ;( ___________________ w31rd0

Currently in ChucK, a parent shred will terminate any child shreds when the parent terminates.
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
I have a lot of examples in my code on me explicitly having to handle this and it both 1) looks ugly and 2) is not that robust.
BTW: would it be possible to grab the id of the child and wait for that is to finish, instead of my current way (chucking a sufficiently large dur to now in the parent after sporking)?
You can make your children explicitly signal they are exiting, like this:
fun void foo( Event e ) { 10::ms => now; <<< "foo", "" >>>; e.signal(); }
fun void bar( Event e ) { 1000::ms => now; <<< "bar", "" >>>; e.signal(); }
Event e1, e2;
spork ~ foo( e1 ); spork ~ bar( e2 );
e1 => now; e2 => now;
Still ugly though ;(
Oops! Discovered that this wouldn't work when "foo" is executed longer than "bar". Here is a slightly improved version: public class Semaphore { 0 => int _counter; Event _event; public void push() { _counter++; } public void pop() { _counter--; if( _counter <= 0 ) { _event.signal(); } } public void wait() { _event => now; } } fun void foo( Semaphore s ) { s.push(); 100::ms => now; <<< "foo", "" >>>; s.pop(); } fun void bar( Semaphore s ) { s.push(); 1000::ms => now; <<< "bar", "" >>>; s.pop(); } Semaphore s; spork ~ foo( s ); spork ~ bar( s ); s.wait(); ___________________ w31rd0

Atte; The current way chuck works makes sense. But (and I don't know "the
prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating.
The problem with this is that childeren may very well be running forever. If a child is structured like this; while (true) { <<<"the world turns around">>>; 1::year => now; } It's never going to finish (lucky world!). What you could do instead is go int the_end; int child_done; fun void child() { untill( the_end) { //do stuff here; potentially stuff that takes a while. 1::second => now; } //only do this after we fall out of the loop due to "the_end" becoming true. 1 => child_done; //at this point the child is going to leave the VM due to becoming "unemployed" } spork ~ child(); 30::second => now; 1 => the_end; untill ( child_done) { //wait for the child to get done, could wait for multiple childeren if need be 5::ms => now; } //only exit now. me.exit(); This should make the parent wait for the child to get done before exiting yet still alows the parent to kill it's childeren. The could be typos in the above but the general idea should be clear? Does that help? Kas.

Hi!
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
Perhaps what we need is a Shred.join( Shred child ), which should let time advance until the child terminates, if ever. And maybe also a Shred.joinAll() that waits for all children shreds. Best, Ge!

would it make sense to somehow chuck something to now for shred joining functionality? it always sort of made semantic sense to me that (using standard built-in functionality) the only way to pass time was to explicitly operate on now. like myShred => now; vs. me.join( myShred ); Its a bit convoluted, but the first way might convey the passage of time more explicitly and more symbolically. Not sure how a joinAll would be worked into this scheme, though. spencer On Jul 26, 2006, at 9:29 AM, Ge Wang wrote:
Hi!
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
Perhaps what we need is a Shred.join( Shred child ), which should let time advance until the child terminates, if ever. And maybe also a Shred.joinAll() that waits for all children shreds.
Best, Ge!
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users

It would add to our "overloadation" but I don't think it makes sense in that now deals with time, be it deterministic or asynchronous (events). PRC On Wed, 26 Jul 2006, Spencer Salazar wrote:
would it make sense to somehow chuck something to now for shred joining functionality? it always sort of made semantic sense to me that (using standard built-in functionality) the only way to pass time was to explicitly operate on now.
like myShred => now; vs. me.join( myShred );
Its a bit convoluted, but the first way might convey the passage of time more explicitly and more symbolically. Not sure how a joinAll would be worked into this scheme, though.
spencer
On Jul 26, 2006, at 9:29 AM, Ge Wang wrote:
Hi!
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
Perhaps what we need is a Shred.join( Shred child ), which should let time advance until the child terminates, if ever. And maybe also a Shred.joinAll() that waits for all children shreds.
Best, Ge!
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users

would it make sense to somehow chuck something to now for shred joining functionality? it always sort of made semantic sense to me that (using standard built-in functionality) the only way to pass time was to explicitly operate on now.
like myShred => now;
In this way you won't be able to spork multiple shreds in parallel. And BTW you can achieve the same result by simply invoking myShred's function without sporking a shred. It would be great to have an implicit children counter in class Shred and a method 'waitForChildren' which returns as soon as all child shreds are terminated. So it could look like this: spork ~ foo(); spork ~ bar(); me.waitForChildren(); (or even make 'waitForChildren' called implicitly?) What you think? ___________________ w31rd0
vs. me.join( myShred );
Its a bit convoluted, but the first way might convey the passage of time more explicitly and more symbolically. Not sure how a joinAll would be worked into this scheme, though.
spencer
On Jul 26, 2006, at 9:29 AM, Ge Wang wrote:
Hi!
The current way chuck works makes sense. But (and I don't know "the prober to do this in concurrent programming) I think it would make more sense to wait for child shreds to finish before terminating. This way a parent wouldn't have to worry how long the child is running, which I think is none of it's business.
Perhaps what we need is a Shred.join( Shred child ), which should let time advance until the child terminates, if ever. And maybe also a Shred.joinAll() that waits for all children shreds.
Best, Ge!

On 7/25/06, Ge Wang
As Kassen mentioned, advancing time in the parent shred will allow children to execute. If no time advance is desired, me.yield() should work.
Actually, what I meant was that at times advancing time can give the shred itself time to execute which I hold to be a bug. Still not at a chucking computer but; <<<"hello world">>>; 1::second => now; <<<"good bye cruel world">>>; me.exit(); I believe this will result in the shred going to shred heaven without leaving it's goodbye note. <<<"nice party">>>; 1::second => now; <<<"hey, is it that time already?">>>; 1::ms => now; me.exit(); This one should be more polite. Note that I only observed this once and that I'm not sure wether it could affect other comands as well as printing to the terminal. I reported on this but I'm not sure it was ever officially on the bug list. Might have been fixed since then, might have been a odd exception that was never reproduced? I'd test this if I were at home. Kas.

Actually, what I meant was that at times advancing time can give the shred itself time to execute which I hold to be a bug.
Still not at a chucking computer but;
<<<"hello world">>>; 1::second => now; <<<"good bye cruel world">>>; me.exit();
I believe this will result in the shred going to shred heaven without leaving it's goodbye note.
I can't seem to reproduce this in 1.2.0.6 at the moment under os x, linux, or windows. Joerg noted that under WindowsXP, some printing does not appear promptly without flushing, and we did add that in 1.2.0.6. So perhaps it's fixed. But it could also still be an issue. Please let us know if this shows up. Best, Ge!
participants (7)
-
Atte André Jensen
-
Ge Wang
-
Kassen
-
Ollie Glass
-
Perry R Cook
-
Spencer Salazar
-
w31rd0