Looking for Monitor example
Chris Muller
afunkyobject at yahoo.com
Sun Mar 19 19:55:09 UTC 2006
That sure does clear it up for me. I now appreciate how this #checkOwnerProcess helps ensure proper usage..
Thanks Boris.
- Chris
----- Original Message ----
From: Boris Gaertner <Boris.Gaertner at gmx.net>
To: The general-purpose Squeak developers list <squeak-dev at lists.squeakfoundation.org>
Sent: Sunday, March 19, 2006 5:08:54 AM
Subject: Re: Looking for Monitor example
Hello,
Attached you find the relevant page from my MVC Tutorial that contains
four versions of a producer/consumer example.
The comment of the Monitor class says that you can signal only from
within the critical section of a monitor.
It is therefore not allowed to write:
monitor1 critical: [" do something "
monitor2 signal ].
The following examples demonstrate that you can (and should) use
one single monitor to do all synchronization. (This is the essential
difference
to semaphores. When you synchronize processes with semaphores,
you will usually need more than one sema.)
And here is a working version of your example. You can try
it immediately in a workspace (with 'inspect').
| producer1 producer2 monitor goal work counter goalReached finished |
goal _ (1 to: 1000) asOrderedCollection.
work _ OrderedCollection new.
counter := 0.
goalReached := false.
finished := Semaphore new.
monitor := Monitor new.
producer1 :=
[
[monitor critical:
[monitor waitUntil: [counter \\5 = 0].
goalReached or: [work add: (counter := counter + 1)].
goalReached := counter >= goal size.
monitor signal
].
goalReached
]
whileFalse.
finished signal.
] .
producer2 :=
[
[monitor critical:
[monitor waitWhile: [counter \\5 = 0].
goalReached or: [work add: (counter := counter + 1)].
goalReached := counter >= goal size.
monitor signal
].
goalReached
]
whileFalse.
finished signal
] .
producer1 forkAt: Processor userBackgroundPriority.
producer2 forkAt: Processor userBackgroundPriority.
finished wait; wait.
goal = work.
----------------------------------------------------------------
Here is a second version that does not use a semaphore to inform the
forking process about termination of both forked processes:
| producer1 producer2 monitor goal work counter goalReached
activeProducers|
goal _ (1 to: 1000) asOrderedCollection.
work _ OrderedCollection new.
counter := 0.
goalReached := false.
activeProducers := 0.
monitor := Monitor new.
producer1 :=
[ monitor critical: [activeProducers := activeProducers + 1].
[monitor critical:
[monitor waitUntil: [counter \\5 = 0].
goalReached or: [work add: (counter := counter + 1)].
" Transcript show: 'P1 '; show: counter printString; show: ' ';
show: activeProducers printString; cr."
goalReached := counter >= goal size.
monitor signal
].
goalReached
]
whileFalse.
monitor critical: [activeProducers := activeProducers - 1.
monitor signal: #finish].
] .
producer2 :=
[monitor critical: [activeProducers := activeProducers + 1].
[monitor critical:
[monitor waitWhile: [counter \\5 = 0].
goalReached or: [work add: (counter := counter + 1)].
"Transcript show: 'P2 '; show: counter printString; show: ' ';
show: activeProducers printString; cr."
goalReached := counter >= goal size.
monitor signal
].
goalReached
]
whileFalse.
monitor critical: [activeProducers := activeProducers - 1.
monitor signal: #finish].
] .
producer1 forkAt: Processor userBackgroundPriority.
producer2 forkAt: Processor userBackgroundPriority.
monitor critical:
[monitor waitUntil: [" Transcript show: 'Test finish cond'; show:
activeProducers printString; cr. "
activeProducers = 0 & (goalReached)]
for: #finish.
].
goal = work
-------------
Hope this helps.
Boris
More information about the Squeak-dev
mailing list
|