From: "kosaki (Motohiro KOSAKI)" Date: 2012-11-26T22:59:28+09:00 Subject: [ruby-dev:46632] [ruby-trunk - Bug #5368][Assigned] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Issue #5368 has been updated by kosaki (Motohiro KOSAKI). Status changed from Closed to Assigned Assignee changed from kosaki (Motohiro KOSAKI) to matz (Yukihiro Matsumoto) Priority changed from High to Normal 現状、ささださんが #1にてCPU使用率が跳ね上がるのだけがバグで、終わらない、かつCtrl-Cも効かなくなるのは仕様という見解を出しているのでそれにそって、r37865でCPU使用率問題を直しました。 さて、このまま閉じてしまっていいのかまったく分からないので、まつもとさん意見をください。 元の起票バグだとensureで無限sleepというちょっとありえなさそうなスクリプトですが、IO.read などでも同様の「終了しない+Ctrl-C効かない」が起こります。これはCtrl-Cが絶対メインスレッドに飛ぶのでサブスレッドが起きれないから。それでも構わないということであれば closeしてください。 だめだと思っている場合は、どのような動作がいいと思っているか教えてください [Feature #1952] の #12でmameさんが選択肢をいくつか列挙してくれていて > どうしても直したいならば、 > > - サブスレッドの終了待ち状態で SIGINT を受け取ったら、 > eTerminateSignal を再送する > - しつこく Ctrl+C を押していればいつか終了できる、かも > > - eTerminateSignal を捕捉できない例外とする > - サブスレッドの ensure が実行されない > > - eTerminateSignal を投げて数秒しても終わってくれない場合、 > 捕捉できない例外を投げる > - サブスレッドの ensure が実行されない危険が緩和されるが > 本質的に解決はしない。あとダサい > > くらいを思いつきましたが、どれも問題がある or 面倒ですね。 とかいうコメントがついています。[Feature #1952]全体を一度読みなおしてからコメントいただけるとなおありがたい ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33960 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/