From: Tassilo Horn Date: 2004-10-09T00:14:44+09:00 Subject: Problems with my first multithreaded Rupy programm Hi, I'm trying to get into Ruby and today it's time for multithreading. Therefore I wanted to write a program which does this: In a tearoom there are three thirsty drinkers. To cook a tea one needs water, tea and a cup. Every one of these three drinkers has one of those items with him. Every time the waiter is called he puts two items on the table. Now one drinker has all the items he needs and cooks his tea. After that he calls the waiter and the fun begins again... Ok, here's what I wrote so far and what produces this output: ,---- | (%:~/tmp/Teadrinker)- ./TeaRoom.rb | WAITER: Looking at the table! | WAITER: Oh, nothing on the table! | WAITER: Putting 1 and 2 on the table. | deadlock 0x4023b798: sleep:J(0x4022603c) (main) - ./TeaRoom.rb:94 | deadlock 0x40225e70: sleep:- - /usr/lib/ruby/1.8/thread.rb:96 | deadlock 0x40225efc: sleep:- - /usr/lib/ruby/1.8/thread.rb:96 | deadlock 0x40225f88: sleep:- - /usr/lib/ruby/1.8/thread.rb:96 | deadlock 0x4022603c: sleep:- - ./TeaRoom.rb:31 | ./TeaRoom.rb:31: Thread(0x4022603c): deadlock (fatal) `---- <----- CODE -----> #! /usr/bin/env ruby require 'thread' # For synchronisation mutex = Mutex.new cv = ConditionVariable.new # items on the table: # 0: cup # 1: water # 2: tea table = [] waiter = Thread.new { while true mutex.synchronize { puts "WAITER: Looking at the table!" if table.length == 0 puts "WAITER: Oh, nothing on the table!" sleep 2 while table[0] == table[1] do table = [rand(3), rand(3)] end $stdout << "WAITER: Putting " << table[0] << " and " << table[1] << " on the table.\n" else puts "WAITER: Why did you call me???" end # Call the waiting tea drinkers cv.broadcast Thread.stop } end } # Mike has a cup (0) mike = Thread.new { while true mutex.synchronize { cv.wait(mutex) if table.include?(1) and table.include?(2) puts "MIKE: Water and tea on table. I'll cook my tea." table = [] sleep 3 puts "MIKE: Drinking my tea. Calling the waiter." # Wake up the waiter-Thread waiter.wakeup sleep 3 puts "MIKE: Now I will read my newspaper." else puts "MIKE: Not what I need." end } end } # Al has water (1) al = Thread.new { while true mutex.synchronize { cv.wait(mutex) if table.include?(0) and table.include?(2) puts "AL: Cup and tea on table. I'll cook my tea." table = [] sleep 3 puts "AL: Drinking my tea. Calling the waiter." # Wake up the waiter-Thread waiter.wakeup sleep 3 puts "AL: Now I will read my newspaper." else puts "AL: Not what I need." end } end } # Ed has tea (2) ed = Thread.new { while true mutex.synchronize { cv.wait(mutex) if table.include?(0) and table.include?(1) puts "ED: Cup and water on table. I'll cook my tea." table = [] sleep 3 puts "ED: Drinking my tea. Calling the waiter." # Wake up the waiter-Thread waiter.wakeup sleep 3 puts "ED: Now I will read my newspaper." else puts "ED: Not what I need." end } end } waiter.join <----- END OF CODE -----> What's wrong with these lines? Much thanks in advance, Tassilo