Created
May 16, 2013 18:20
Revisions
-
egonSchiele created this gist
May 16, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,92 @@ require 'thread' class Waiter def initialize @mutex = Mutex.new end def can_eat? philosopher left = philosopher.left_fork right = philosopher.right_fork @mutex.synchronize do if !left.used && !right.used left.used = true right.used = true return true else return false end end end def stop_eating philosopher @mutex.synchronize do philosopher.left_fork.used = false philosopher.right_fork.used = false end end end class Philosopher attr_accessor :left_fork, :right_fork def initialize(name, left_fork, right_fork, waiter) @name = name @left_fork = left_fork @right_fork = right_fork @waiter = waiter think end def think puts "Philosopher #@name is thinking..." sleep(rand()) puts "Philosopher #@name is hungry..." dine end def dine while !@waiter.can_eat?(self) think end puts "Philosopher #@name eats..." sleep(rand()) puts "Philosopher #@name belches" @waiter.stop_eating(self) think end end n = 5 forks = [] class Fork attr_accessor :used def initialize @used = false end end (1..n).each do |i| forks << Fork.new end threads = [] waiter = Waiter.new (1..n).each do |i| threads << Thread.new do if i < n left_fork = forks[i] right_fork = forks[i+1] else # special case for philosopher #5 because he gets forks #5 and #1 # and the left fork is always the lower id because that's the one we try first. left_fork = forks[0] right_fork = forks[n] end Philosopher.new(i, left_fork, right_fork, waiter) end end threads.each {|thread| thread.join}