2014年1月18日土曜日

Ruby: mutex.sleep は他にスレッドがないとデッドロック判定になる

Ruby で Queue を使った以下のコードはデッドロック判定で停止する:

require 'thread'

q = Queue.new
q.pop

push するスレッドが別に動いていないのでデッドロック判定になる。thread.rb にある Queue.pop を読むと、以下が大本であることがわかる:

irb(main):001:0> m = Mutex.new
=> #
irb(main):002:0> m.lock
=> #
irb(main):003:0> m.sleep
fatal: deadlock detected
 from (irb):3:in `sleep'
 from (irb):3
 from /usr/local/ruby_1.9.3/bin/irb:12:in `
'
mutex.sleep でデッドロック判定になる。普段は他にもスレッドが動いている状況で Queue なり Mutex を使う訳で、別途スレッドを動かして m.sleep を呼んでみると:
irb(main):004:0> Thread.new{sleep 5}
=> #
irb(main):005:0> m.sleep

デッドロック判定は出なくなる。

そんな訳で、mutex.sleep は他にスレッドがないとデッドロック判定となるようだ。 マルチスレッドなコードで終わり方をいい加減にすると陥る可能性がある。

0 件のコメント:

コメントを投稿