Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Dining philosophers in Ruby with Celluloid. Modified from https://gist.github.com/bugant/4984042
require 'rubygems'
require 'celluloid'
class Waiter
include Celluloid
FORK_FREE = 0
FORK_USED = 1
attr_reader :philosophers
attr_reader :forks
attr_reader :eating
def initialize(forks)
@philosophers = []
@eating = []
@forks = Array.new(forks, FORK_FREE)
end
def welcome(philosopher)
@philosophers << philosopher
philosopher.async.think
end
def hungry(philosopher)
pos = @philosophers.index(philosopher)
left_pos = pos
right_pos = (pos + 1) % @forks.size
if @forks[left_pos] == FORK_FREE && @forks[right_pos] == FORK_FREE
@forks[left_pos] = FORK_USED
@forks[right_pos] = FORK_USED
@eating << philosopher
philosopher.async.eat
else
# it's not your turn, keep thinking
philosopher.async.think
end
end
def drop_forks(philosopher)
pos = @philosophers.index(philosopher)
left_pos = pos
right_pos = (pos + 1) % @forks.size
@forks[left_pos] = FORK_FREE
@forks[right_pos] = FORK_FREE
@eating -= [philosopher]
philosopher.async.think
end
end
class Philosopher
include Celluloid
attr_reader :name
attr_reader :waiter
def initialize(name, waiter)
@name = name
@waiter = waiter
waiter.async.welcome(Actor.current)
end
def think
puts "#{name} is thinking"
sleep(rand)
puts "#{name} gets hungry"
waiter.async.hungry(Actor.current)
end
def eat
puts "#{name} is eating"
sleep(rand)
puts "#{name} burps"
waiter.async.drop_forks(Actor.current)
end
end
names = %w{Heraclitus Aristotle Epictetus Schopenhauer Popper}
waiter = Waiter.new(names.size)
philosophers = names.map {|name| Philosopher.new(name, waiter)}
# The main thread is done! Sleep forever
sleep
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.