process synchronization

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

process synchronization

Sylvain pralon
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.

Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

kobetic
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


Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

Ladislav Lenart
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 wouldn't recommend the use of busy wait (in any case).

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

Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

Filip Stadnik
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:
> 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 wouldn't recommend the use of busy wait (in any case).

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


Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

Josef Springer
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,

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.



--
Signature mit freundlichen Grüßen / best regards,
Josef Springer
(Geschäftsleitung/Management)

Postal
Address
[hidden email]
Orlando-di-Lasso Str. 2
D-85640 Putzbrunn
Phone
Office
+49 (0)89 600 6920


Phone
Fax
+49 (0)89 600 69220


Web
Web
http://www.joops.com



JOOPS
-- the software company --

 

Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

Reinout Heeck
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
-

jas
Reply | Threaded
Open this post in threaded view
|

Re: process synchronization

jas
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.
>