Hi,
I have a problem with the synchronization of two processes created by the fork message send to a BlockContext. my code : ... process1 := [ ... ] fork. process2 := [ ... ] fork. [process1 isTerminated & process2 isTerminated] whileFalse:[]. ... the documentation is weak for this point and I did not manage to find a solution. I saw the method isTerminated which allow to test if the test is over but it seems it do not do what I am waiting for. I have to interrupt all processes by pressing CTRL+Y and when I inspect "[process1 isTerminated & process2 isTerminated]" it gives True. I do not understand why it stay in this while block. please help. |
Sylvain Pralon wrote:
> Hi, > > I have a problem with the synchronization of two processes created by > the fork message send to a BlockContext. > > my code : > ... > > process1 := [ ... ] fork. > process2 := [ ... ] fork. > [process1 isTerminated & process2 isTerminated] whileFalse:[]. > > ... > > the documentation is weak for this point and I did not manage to find a > solution. > I saw the method isTerminated which allow to test if the test is over > but it seems it do not do what I am waiting for. > I have to interrupt all processes by pressing CTRL+Y and when I inspect > "[process1 isTerminated & process2 isTerminated]" it gives True. > I do not understand why it stay in this while block. All these 3 processes run at the same priority. Within the same priority level the processes are non-preemptive, i.e. a process will keep running until 1) it finishes, or 2) it is suspended either explicitly (#suspend) or waiting on a Semaphore or a Delay, or 3) it explicitly gives up control using #yield The process will also be interrupted by any higher priority processes, but that doesn't have an impact on scheduling within the same priority level (in normal case), so once the higher priority processes are done (or suspended) the same process will get the control back. So in your example your main process will keep spinning in a tight loop and won't give the other two process any chance to run. When you interrupt the process with Ctrl+Y, that finally frees the processor for the other 2 processes and by the time you inspect the expression they are most likely long done. So that's why the expression gives you true at that point. So the lesson is, don't expect to catch up with processes with a mouse and keyboard, they are wicked fast :-). You might get a more accurate picture of using Ctrl+\, which suspends all user processes at once and opens the ProcesssMonitor on them. Others already suggested solutions. HTH, Martin |
In reply to this post by Sylvain pralon
Sylvain Pralon wrote:
> Hi, > > I have a problem with the synchronization of two processes created by > the fork message send to a BlockContext. > > my code : > ... > > process1 := [ ... ] fork. > process2 := [ ... ] fork. > [process1 isTerminated & process2 isTerminated] whileFalse:[]. I would prefer something like this: | p1 p1Sem p2 p2Sem | p1Sem := Semaphore new. p2Sem := Semaphore new. p1 := [Transcript show:'P1 started'. Transcript cr. (Delay forSeconds: 1) wait. Transcript show: 'P1 finished'. Transcript cr. p1Sem signal]. p2 := [Transcript show: 'P2 started'. Transcript cr. (Delay forSeconds: 2) wait. Transcript show: 'P2 finished'. Transcript cr. p2Sem signal]. p1 fork. p2 fork. Transcript show: 'Waiting for P1'. Transcript cr. p1Sem wait. Transcript show: 'Waiting for P2'. Transcript cr. p2Sem wait. Transcript show: 'Free to go'. Transcript cr. This way, the waiting process does not consume CPU while waiting... Hope this helps, Ladislav Lenart |
Hi Sylvain,
I would also recommend you to read relevant chapters from the free smalltalk books: 1) Smalltalk by Example (by Alec Sharp) - Chapters 16, 17 http://www.iam.unibe.ch/~ducasse/FreeBooks/ByExample/ 2) Introduction to Smalltalk (by Ivan Tomek) - Chapter 13 http://www.iam.unibe.ch/~ducasse/FreeBooks/Joy/ You can find all the free smalltalk books at http://www.iam.unibe.ch/~ducasse/FreeBooks.html Cheers, Filip On 02/11/06, Ladislav Lenart <[hidden email]> wrote: Sylvain Pralon wrote: |
In reply to this post by Sylvain pralon
Try e.g.
| process1Terminated | process1Terminated := false. process1 := [... process1Terminated := true] fork. [process1Terminated] whileFalse: [... (Delay forSeconds: 5) wait] Josef Sylvain Pralon wrote: Hi, --
Josef Springer (Geschäftsleitung/Management)
|
In reply to this post by kobetic
On Nov 2, 2006, at 10:40 AM, Martin Kobetic wrote: > Sylvain Pralon wrote: >> >> ... >> process1 := [ ... ] fork. >> process2 := [ ... ] fork. >> [process1 isTerminated & process2 isTerminated] whileFalse:[]. >> ... > > Others already suggested solutions. > But I missed the obvious one: sem := Semaphore new. process1 := [ ... sem signal] fork. process2 := [ ... sem signal] fork. sem wait. sem wait. ... R - |
In reply to this post by Sylvain pralon
At 02:17 AM 11/2/2006, Sylvain Pralon wrote:
>Hi, > >I have a problem with the synchronization of two processes created by the fork message send to a BlockContext. >my code : > ... > > process1 := [ ... ] fork. > process2 := [ ... ] fork. > [process1 isTerminated & process2 isTerminated] whileFalse:[]. > > ... > >the documentation is weak for this point and I did not manage to find a solution. This is a general synchronization issue (i.e. not specific to Smalltalk). One always needs to know how the current environment schedules a forked process. There are 6 possibilities: 1) queue the forked process (continue running the forker) 2) push the forked process (continue running the forker) 3) queue the forked process, yield (begin running process at front of queue) 4) queue the forker, queue the forked process, switch (begin running process at front of queue) 5) push the forked process, yield (begin running the forked process) 6) push the forker, push the forked process, switch (begin running the forked process), Your example would work for cases 3,5, and 6, but would not work for cases 1,2, and 4. Since your example doesn't work, your Smalltalk dialect must be scheduling a forked process as in case 1, 2 or 4. The bit that is the same for all 3 cases is that the forker runs before the forked process, and your example can't deal with that - it becomes in effect, an infinite loop. TSTCP make your example Work, is changing it to this: process1 := [ ... ] fork. process2 := [ ... ] fork. [process1 isTerminated & process2 isTerminated] whileFalse: [self yield]. ( You can either replace {self yield} in the above, with {Processor yield}, or define a #yield method on Object, as: Object>>yield ^Processor yield whichever you prefer. ) HTH. Regards, -cstb >I saw the method isTerminated which allow to test if the test is over but it seems it do not do what I am waiting for. >I have to interrupt all processes by pressing CTRL+Y and when I inspect "[process1 isTerminated & process2 isTerminated]" it gives True. >I do not understand why it stay in this while block. > >please help. > |
Free forum by Nabble | Edit this page |