From: Yui NARUSE Date: 2011-12-14T15:00:21+09:00 Subject: [ruby-dev:44995] [ruby-trunk - Bug #5757] main threadがreadやselectで待っていると、^C でなかなか死なない Issue #5757 has been updated by Yui NARUSE. ruby -v changed from - to ruby 2.0.0dev (2011-12-12 trunk 34015) [x86_64-freebsd9.0] レビューありがとうございます。 > いや、スレッドがGVL競合してなくて、ubf_selectを登録したけどまだselectを読んでないとき > ubf_selectのkill(VTALRM) はスカるので、もう一回ubf_select_eachが呼ばれるようにする > トリックが必要だという認識です。 そのもう一回も外しちゃう可能性って無いんでしょうか。 どちらかというと、rb_thread_kill 側で確実に止めを刺す用にするべきな気もします。 rb_thread_kill で rb_thread_wakeup_timer_thread() というのも考えていたんですが、 とりあえず [ruby-dev:44992] で動いてるっぽかったので、各プラットフォームでの確認の利便性を鑑み、 r34038 にてコミットしてます。 ---------------------------------------- Bug #5757: main threadがreadやselectで待っていると、^C でなかなか死なない http://redmine.ruby-lang.org/issues/5757 Author: Yui NARUSE Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.0.0dev (2011-12-12 trunk 34015) [x86_64-freebsd9.0] FreeBSD 9 にて、 ./ruby と起動して ^C を投げてもなかなか死にません。 ./miniruby でも -e'$stdin.read' でも同じです。 仕組みとしては、main thread が read や select で待つ場合、最近は blocking region で unblock.func に ubf_select を設定するわけですが、この時にシグナルが来ると、 1. どこかのスレッドの sighandler が呼ばれて、rb_thread_wakeup_timer_thread() が呼ばれる 2. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる 3. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる 4. タイマースレッドが起きて、thread_timer() -> timer_thread_function() -> rb_threadptr_check_signal() -> rb_threadptr_interrupt() -> (th->unblock.func)(th->unblock.arg) -> ubf_select() -> rb_thread_wakeup_timer_thread() が呼ばれる ... 対策はいくつかあり得ると思うのですが、例えば、ubf_select() から rb_thread_wakeup_timer_thread() を呼ばないようにするとか -- http://redmine.ruby-lang.org