[Newbies] Process Scheduling (was Re: BlockClosure>>fork problem)

Bert Freudenberg bert at freudenbergs.de
Tue Feb 20 11:38:29 UTC 2007


On Feb 20, 2007, at 11:05 , Michael Davies wrote:

> George,
>
> You'll find that writing to the Transcript always slows things down. I
> assume it's the time for writing to the Transcript that also causes
> the second process to start after a different interval each time.

Besides, it interferes with processes because it has a Mutex  
nowadays. Which is good, but it distorts what you would observe  
without the Transcript involved.

> Writing the results into an OrderedCollection will be much faster, and
> more predictable:
>
> a := OrderedCollection new.
> [10 timesRepeat: [a addLast: '2'. (Delay forMilliseconds: 1) wait]]  
> fork.
> [10 timesRepeat: [a addLast: '1'. (Delay forMilliseconds: 1) wait]]  
> fork.
> a inspect.
>
> consistently gives 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1.

This is because waiting on Delay (or, rather on the Semaphore inside)  
causes the current process to block, and the next process on the same  
priority to run. The same could be achieved by "Processor yield"  
instead of waiting on the Delay. This is "cooperative". Or, you could  
have a higher-priority scheduler that time-slices the lower-priority  
ones by suspending them in turn, which does not need cooperation.

> Without the delay:
>
> a := OrderedCollection new.
> [10 timesRepeat: [a addLast: '2']] fork.
> [10 timesRepeat: [a addLast: '1']] fork.
> a inspect.
>
> consistently gives 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1.

These processes are too short-lived to ever get interrupted by a  
higher priority process. So the first one runs to completion, then  
the second one. Try this instead:

a := String new writeStream.
p1 := [[a nextPut: $1] repeat] forkAt: Processor userBackgroundPriority.
p2 := [[a nextPut: $2] repeat] forkAt: Processor userBackgroundPriority.
10 timesRepeat: [(Delay forMilliseconds: 1) wait].
p1 terminate.
p2 terminate.
a contents

This puts the two processes into a lower priority than the UI  
process. We then stop the UI process 10 times for one millisecond -  
this is our scheduler. Each time, the next lower-priority process is  
given time to run - that is the default scheduling behavior. The  
result are nicely alternating runs of ones and twos as you would  
expect: '111111111122222222222111111111111122222222222...'

- Bert -




More information about the Beginners mailing list