Created
May 16, 2013 18:20
-
-
Save egonSchiele/5593864 to your computer and use it in GitHub Desktop.
Dining philosophers using locks in Ruby. This implements a Waiter who is in charge of forks.
This file contains 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 characters
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} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment