From: Markus Date: 2004-10-16T14:07:53+09:00 Subject: Re: Again some problem with my multithreaded teadrinker app I think (and this late in a long day for me, so I may be wrong) that the problem is that you are using broadcast to wake the drinkers. This causes a race condition (as they all assess the table contents "at once") and an eventual deadlock. I tried a quick test of 1) replacing the broadcast with a signal, and 2) adding an else-clause so that the drinker re-signals if what he finds on the table is not what he's wanting. It makes sense & seems to work, but I'm too pooped to vouch for it beyond that. -- Markus On Fri, 2004-10-15 at 10:49, Tassilo Horn wrote: > Markus writes: > > > I'd suggested this before (as the solution to your first problem) but it > > seemed to have gotten missed--the nesting of your looping/locking needs > > to be swapped. In the present case, reversing both of the " > > mutex.synchronize"/"while true" pairs (and their associated "}"/"end" > > pairs) should fix the problem. > > It seems to work if I start many threads, but if I only use three I get > an deadlock after one or two drinkers had their tea: > > (%:~/tmp/teadrinkers--mainline--0.3--patch-1)- ./TeaRoom.rb 3 > Starting Drinker0 > Starting Drinker1 > Starting Drinker2 > WAITER: Looking at the table! > WAITER: Oh, nothing on the table! > WAITER: Putting 2 and 1 on the table. > WAITER: Waiting for new appointments... > Drinker0: Tea and Water on table. I'll cook my tea! > Drinker0: Drinking my tea. I call the waiter again. > Drinker0: Now I'll read my newspaper. > WAITER: Looking at the table! > WAITER: Oh, nothing on the table! > WAITER: Putting 0 and 1 on the table. > WAITER: Waiting for new appointments... > Drinker2: Cup and Water on table. I'll cook my tea! > Drinker2: Drinking my tea. I call the waiter again. > Drinker2: Now I'll read my newspaper. > WAITER: Looking at the table! > WAITER: Oh, nothing on the table! > WAITER: Putting 1 and 0 on the table. > WAITER: Waiting for new appointments... > deadlock 0x4022b0dc: sleep:- - /usr/lib/ruby/1.8/thread.rb:195 > deadlock 0x40240798: sleep:J(0x4022acb8) (main) - ./TeaRoom.rb:81 > deadlock 0x4022acb8: sleep:- - /usr/lib/ruby/1.8/thread.rb:195 > deadlock 0x4022ade4: sleep:- - /usr/lib/ruby/1.8/thread.rb:195 > deadlock 0x4022af60: sleep:- - /usr/lib/ruby/1.8/thread.rb:195 > /usr/lib/ruby/1.8/thread.rb:195: Thread(0x4022af60): deadlock (fatal) > > > P.S. If the reason isn't clear, ask yourself when/under what condition > > (in the code as posted) did it ever leave the synchronize block? > > Never. And when the waiter calls drinker_cv.broadcast() always the > thread who entered the mutex.synchronize-block first and obtained the > lock first is woken up. Right? > > Thanks for your help, > Tassilo