# Dining Philosophers
# \ # /
# # #
# /#|#\
#
# Philosophers
# \ 0 /
# 4 1
# /3|2\
#
# Chopsticks
# 4 # 0
# # #
# 3#2#1
require 'thread'
# Hungry or meditating
class Philosopher
def initialize(left:, right:)
@left, @right = left, right
loop do
meditate
hungry
end
end
def meditate
puts "#{self} is meditating..."
sleep(rand 1..3)
puts "#{self} is hungry..."
end
def hungry
pick_up_chopsticks
end
def pick_up_chopsticks
loop do
@left.lock
puts "#{self} has one chopstick..."
break if @right.try_lock
puts "#{self} cannot pickup second chopstick"
@left.unlock
end
puts "#{self} has the second chopstick!", "#{self} eats..."
eat
end
def eat
sleep(rand 1..3)
puts "#{self} done eating."
@right.unlock
@left.unlock
end
end
chopsticks = []
5.times { chopsticks << Mutex.new }
pool = []
pool << Thread.new { Philosopher.new left: chopsticks[0], right: chopsticks[1] }
pool << Thread.new { Philosopher.new left: chopsticks[1], right: chopsticks[2] }
pool << Thread.new { Philosopher.new left: chopsticks[2], right: chopsticks[3] }
pool << Thread.new { Philosopher.new left: chopsticks[3], right: chopsticks[4] }
pool << Thread.new { Philosopher.new left: chopsticks[4], right: chopsticks[0] }
pool.each(&:join)