From: mame@... Date: 2018-04-06T05:28:24+00:00 Subject: [ruby-dev:50521] [Ruby trunk Bug#5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Issue #5368 has been updated by mame (Yusuke Endoh). 現状の整理です。 ``` Thread.new do begin sleep ensure sleep end end ``` もともとは上のコードで CPU 使用率 100% でフリーズしていたという問題でしたが、現状は次のようになってます。 * CPU 使用率 100 % は解決済 * Ctrl+C から 1 秒くらいで終了する rb_thread_terminate_all は、永遠に待つのではなく、1 秒ごとにポーリングするようになったためです(#14090)。つまり現状は、子スレッドがおそすぎる ensure 処理をやってる間に Ctrl+C が来たら 1 秒くらいで終了するようになっています。 #1952 で、rb_thread_terminate_all の後に子スレッドが生きていると SEGV するケース(子スレッドから親に例外を投げる)を自分が示しましたが、このケース自体は kosaki さんによって対応済みのようです。他に問題があるかはわかりません。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-71403 * Author: Glass_saga (Masaki Matsushita) * Status: Assigned * Priority: Normal * Assignee: kosaki (Motohiro KOSAKI) * Target version: * ruby -v: - * Backport: ---------------------------------------- =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 ---Files-------------------------------- patch.diff (795 Bytes) -- https://bugs.ruby-lang.org/