Queue の実験

Queue の実験

★を入れないと deadlock になる。Queue#pop はキューが空だと永遠に待つ。その時に sleep すると駄目らしい。当たり前か?

require 'thread'

queue = Queue.new

push1 = Thread.new{ 
  [:resource11, :resource12, :resource13, :resource14].each{|r|
    sleep(1)
    queue.push(r)
    p [:push1,r]
  }
}

push2 = Thread.new{ 
  [:resource21, :resource22, :resource23, :resource24].each{|r|
    sleep(0.7)
    queue.push(r)
    p [:push2,r]
  }
}

pop1 = Thread.start do
  while resource = queue.pop
    p [:pop,resource, queue, queue.size]
    break unless push1.alive? || push2.alive? || !queue.empty?  # ←★
    sleep(1)
  end
end

#push1.join
#push2.join
pop1.join
C:\Apollo>ruby 1.rb
[:pop, :resource21, #<Queue:0x293f86c>, 0]
[:push2, :resource21]
[:push1, :resource11]
[:push2, :resource22]
[:pop, :resource11, #<Queue:0x293f86c>, 1]
[:push1, :resource12]
[:push2, :resource23]
[:pop, :resource22, #<Queue:0x293f86c>, 2]
[:push2, :resource24]
[:push1, :resource13]
[:pop, :resource12, #<Queue:0x293f86c>, 3]
[:push1, :resource14]
[:pop, :resource23, #<Queue:0x293f86c>, 3]
[:pop, :resource24, #<Queue:0x293f86c>, 2]
[:pop, :resource13, #<Queue:0x293f86c>, 1]
[:pop, :resource14, #<Queue:0x293f86c>, 0]
:end