Skip to content

Instantly share code, notes, and snippets.

@kliph
Created October 28, 2017 23:05
Show Gist options
  • Save kliph/9466ce6384a25412ccd3346c6f8be7b9 to your computer and use it in GitHub Desktop.
Save kliph/9466ce6384a25412ccd3346c6f8be7b9 to your computer and use it in GitHub Desktop.
Dining witches with Mutex locks
require 'thread'
class Witch
def initialize(name, left_wand, right_wand)
@name = name
@left_wand = left_wand
@right_wand = right_wand
while true
conjure
dine
end
end
def conjure
puts "Witch #@name is conjuring..."
sleep rand()
puts "Witch #@name needs food badly..."
end
def dine
while true
@left_wand.lock
puts "Witch #@name has one wand to summon food..."
if @right_wand.try_lock
break
else
puts "Witch #@name cannot grab a second wand"
@left_wand.unlock
end
end
puts "Witch #@name has the second wand!"
puts "Witch #@name summons food and eats..."
sleep rand()
puts "Witch #@name finishes eating..."
@left_wand.unlock
@right_wand.unlock
end
end
n = 5
wands = (1..n).reduce([]) do |acc, i|
acc << Mutex.new
end
threads = (1..n).reduce([]) do |acc, i|
acc << Thread.new do
if i < n
left_wand = wands[i]
right_wand = wands[i + 1]
else
# last witch wraps to use wand 5 and 1
left_wand = wands[0]
right_wand = wands[n]
end
Witch.new(i, left_wand, right_wand)
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