Hi Folks,
I think the problem is that we have race conditions due to the fact
that Transcript is not thread-safe (as pointed out by Matthew). We
can fix this either by making it thread-safe (using a mutex semaphore
as suggested by Ron), or by simply enclosing our accesses to
Transcript with a mutex. This would allow Jason to safely experiment
with the plain semaphores.
This now works the way we expect it to.
semA := Semaphore new.
semB := Semaphore new.
semT := Semaphore forMutualExclusion.
[ semT critical: [Transcript show: 'b1'; cr].
semB signal.
semA wait.
semT critical: [Transcript show: 'b2'; cr]
] fork.
[ semT critical: [Transcript show: 'a1'; cr].
semA signal.
semB wait.
semT critical: [Transcript show: 'a2'; cr]
] fork.
Oscar
On Sep 30, 2007, at 4:20, Ron Teitelbaum wrote:
Hi Jason,
I’m not really sure what you are trying to do but this works too.
semA := Semaphore forMutualExclusion.
semB := Semaphore new.
[semA critical: [Transcript show: 'b1'; cr. semB signal. semA wait.].
Transcript show: 'b2'; cr.
semB signal.
] fork.
[semB critical: [Transcript show: 'a1'; cr. semA signal. semB wait.].
Transcript show: 'a2'; cr.
] fork.
Semaphore forMutualExclusion signals the semaphore so that you can
get into
the first critical block.
The critical block is what does the code blocking.
SemB signal allows the second thread in while semA wait keeps the
block from
exiting.
Then semA signal allows the first block to continue, but semB wait
keeps the
second block from exiting.
Then semB signal allows the second block to continue, and since
both forked
blocks complete they disappear.
There are a lot of ways to make this easier, but I think it’s good
to look
at these constructs closely, if you are planning to work with threads.
Check out SharedQueue for thread safe processing. Also have a look
at Mutex
for other Semaphore behavior.
Good luck!
Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
www.USMedRec.com
________________________________________
From: Jason Shoemaker
This is probably a safer version. It works for me.
semA := Semaphore new.
semB := Semaphore new.
thread1 := [Transcript cr; nextPutAll: 'b1'. semB signal. semA wait.
Transcript cr; nextPutAll: 'b2'. ] fork.
thread2 := [Transcript cr; nextPutAll: 'a1'. semA signal. semB wait.
Transcript cr; nextPutAll: 'a2'.] fork.
[thread1 isTerminated and: [thread2 isTerminated]] whileFalse:
[(Delay forMilliseconds: 100) wait].
Transcript flush
Now to move on to another pattern.
JTS
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
Beginners@lists.squeakfoundation.org
http://lists.squeakfoundation.org/mailman/listinfo/beginners