From: "tarui (Masaya Tarui)" Date: 2012-11-27T05:09:26+09:00 Subject: [ruby-dev:46636] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Issue #5368 has been updated by tarui (Masaya Tarui). 1.8の挙動の方がバグっぽいですけれどねぇ Ctrl-Cでensureの実行が保証されず、終わってしまうのは大きな問題だと思います。 現にTimeoutでensureが飛ばされるので困ってcontrol_interruptをなどを導入しようと しているのだと理解しています。kill -KILLしないと死なないプロセスは良くある事で、 これはensureを必ず実行しようとする事とのトレードオフだと思います。 デフォルトでの挙動ではCtrl-CでIntrrupt例外を再送するようにして、 ensure節中ではIntrrupt例外に対して:on_blockingにしておいてやると、 ユーザーが望めば:neverにする事が出来て実行が保証でき、かつ普通にensureを書いてる分には Ctrl-C連打で上記sleepやio待ちもキャンセル出来て良いんじゃないでしょうか? (:immediateだと設定を変えようとしてる間に例外が飛んで来て飛ばされる可能性があるので) ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33979 Author: Glass_saga (Masaki Matsushita) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: 2.0.0 ruby -v: - =begin 次のコードを実行するとCPU使用率が跳ね上がった状態になりインタプリタが終了しません。 Thread.new do begin sleep ensure sleep end end 現在のrb_thread_terminate_allでは最初に1回だけ生きているスレッドに対してterminate_iを実行していますが、ensure節でsleepするようなThreadがあると、そのThreadは寝たままになってしまいwhile(!rb_thread_alone())が無限ループになってしまいます。 while(!rb_thread_alone())の毎回のループでカレントスレッドがメインスレッドであった場合に、生きているスレッドに対してterminate_iを実行するようなpatchを書いたところ、このバグは再現しなくなりました。 patchを添付します。patchの適用後もtest-allをパスします。 =end -- http://bugs.ruby-lang.org/