Timeout
timeoutを使うと、任意の処理の実行時間をチェックし、指定時間をオーバーした場合例外を発生させることができます。
require 'timeout' # 0.1秒以内に処理が終わらない場合、タイムアウトする。 timeout(0.1) { sleep 1 puts "end" }
実行結果です。
xxx/timeout.rb:54: execution expired (Timeout::Error) from xxx/timeout.rb:56:in `timeout' from xxx/timeout.rb:76:in `timeout' from xxx/timeout.rb:5
「timeout による割り込みは Thread によって実現されています。 ... Ruby のスレッドが割り込めない処理に対して timeout は無力です。」とのこと。ということは、Thread#criticalを設定してスレッド切り替えを抑制したらタイムアウトしないはず。
require 'timeout' Thread.critical = true # スレッド切り替えを抑制 timeout(0.1) { sleep 1 puts "end" }
実行結果です。実行時エラーになりました。ふむ。
xxx/timeout.rb:49:in `timeout': timeout within critical session (ThreadError) from xxx/timeout.rb:76:in `timeout' from xxx/notimeout.rb:5