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

Reply via email to