Issue #5368 has been reported by Masaki Matsushita. ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない http://redmine.ruby-lang.org/issues/5368 Author: Masaki Matsushita Status: Open Priority: Normal Assignee: Category: core Target version: 1.9.x ruby -v: ruby 1.9.4dev (2011-09-26 trunk 33338) [x86_64-linux] =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
on 2011-09-26 06:51
on 2011-09-26 07:24
(2011/09/25 21:51), Masaki Matsushita wrote:
>
現在のrb_thread_terminate_allでは最初に1回だけ生きているスレッドに対してterminate_iを実行していますが、ensure節でsleepするようなThreadがあると、そのThreadは寝たままになってしまいwhile(!rb_thread_alone())が無限ループになってしまいます。
ここで,バグとは何でしょうか.
(1) CPU 使用率がはねあがる
(2) プロセスが死なない
(1) が問題というのは理解できます.あまり文句がないんで放置している部分
です.直そうと思えば,正しく他のスレッドを待ち合わせをすればできると思っ
ています.
(2) については仕様です.ご提案の修正方法では,とにかく生きていたら殺
す,ということをしていますが,例えば他のスレッドで何か時間のかかる終了処
理をしていた場合(例えば,終了時にネットワークで外部に情報を送る,という
ようなことをしている場合),それを強制的に止めてしまうため,まずいことに
なります.
ということで,これに関しては,現状だと仕様かな,と思いますが,もっと良
い仕様があれば,ご提案頂けと助かります.
on 2011-09-26 15:41
2011$BG/(B9$B7n(B26$BF|(B14:24 SASADA Koichi <ko1@atdot.net>: >> > > $B!!(B(2) $B$K$D$$$F$O;EMM$G$9!%$4Ds0F$N=$@5J}K!$G$O!$$H$K$+$/@8$-$F$$$?$i;&(B > $B$9!$$H$$$&$3$H$r$7$F$$$^$9$,!$Nc$($PB>$N%9%l%C%I$G2?$+;~4V$N$+$+$k=*N;=h(B > $BM}$r$7$F$$$?>l9g!JNc$($P!$=*N;;~$K%M%C%H%o!<%/$G30It$K>pJs$rAw$k!$$H$$$&(B > $B$h$&$J$3$H$r$7$F$$$k>l9g!K!$$=$l$r6/@)E*$K;_$a$F$7$^$&$?$a!$$^$:$$$3$H$K(B > $B$J$j$^$9!%(B > > $B!!$H$$$&$3$H$G!$$3$l$K4X$7$F$O!$8=>u$@$H;EMM$+$J!$$H;W$$$^$9$,!$$b$C$HNI(B > $B$$;EMM$,$"$l$P!$$4Ds0FD:$1$H=u$+$j$^$9!%(B C$B8@8l$@$C$F(Bat_exit()$B$G(Bsleep()$B$7$?$i;`$J$J$$$7!"(BC++$B$@$C$F%G%9%H%i%/%?$G(Bsleep()$B$7$?$i(B $B;`$J$J$$$7$M$(!#(B $B%W%m%0%i%_%s%08@8l$O%"%[$J%3!<%I$K$?$$$7$F%"%[$J?6$kIq$$$r$9$k$N$O$=$&$$$&$b$N$H$$$&5$$,$7$^$9!#8D?ME*$K$O!#(B ensure$B$K(Bsleep$B$r=q$/$3$H$,Hr$1$k$3$H$,IT2DG=!#$H$$$&OC$K$J$k$H$^$?$A$g$C$HOC$,JQ$o$C$F$/$k$+$H(B $B;W$$$^$9$,!"$=$&$$$&Nc$O;W$$$D$-$^$;$s$G$7$?!#(B
on 2011-09-26 16:04
$B9bHx$H?=$7$^$9!#(B > $B!!(B(2) $B$K$D$$$F$O;EMM$G$9!%$4Ds0F$N=$@5J}K!$G$O!$$H$K$+$/@8$-$F$$$?$i;&(B > $B$9!$$H$$$&$3$H$r$7$F$$$^$9$,!$Nc$($PB>$N%9%l%C%I$G2?$+;~4V$N$+$+$k=*N;=h(B > $BM}$r$7$F$$$?>l9g!JNc$($P!$=*N;;~$K%M%C%H%o!<%/$G30It$K>pJs$rAw$k!$$H$$$&(B > $B$h$&$J$3$H$r$7$F$$$k>l9g!K!$$=$l$r6/@)E*$K;_$a$F$7$^$&$?$a!$$^$:$$$3$H$K(B > $B$J$j$^$9!%(B $B$3$l$O!V(Bensure$B@a$N<B9TCf$K;_$a$k$N$O(BNG$B!W$H$$$&$3$H$G$9$h$M(B? $B$$$^$N<BAu(B (rev.33339) $B$G$O!"(Bensure$B@a$N<B9TCf$G$"$C$F$b!"(Bterminate$B$5$l$?$i(B ($B30B&$K$5$i$J$k(Bensure$B@a$,$J$1$l$P(B) $B$U$D$&$K=*N;$9$k$N$G!"DTjm$,9g$o$J$$5$$,$7$^$9!#(B
on 2011-09-26 16:53
(2011/09/26 7:03), m_takao wrote: > $B$3$l$O!V(Bensure$B@a$N<B9TCf$K;_$a$k$N$O(BNG$B!W$H$$$&$3$H$G$9$h$M(B? > $B$$$^$N<BAu(B (rev.33339) $B$G$O!"(Bensure$B@a$N<B9TCf$G$"$C$F$b!"(Bterminate$B$5$l$?$i(B > ($B30B&$K$5$i$J$k(Bensure$B@a$,$J$1$l$P(B) $B$U$D$&$K=*N;$9$k$N$G!"DTjm$,9g$o$J$$5$$,$7$^$9!#(B $B!!$4;XE&$NDL$j!$!V:G=i$N(B1$B2s$@$1$OI,$:(B ensure $BCf$G$b6/@)E*$K;_$a$F$7$^(B $B$&!W$H$$$&;EMM$K$J$C$F$$$^$9$M!%8=>u$G$O!$(Bensure $BCf!J8e=hM}Cf!K$G$O$J$$(B $B$3$H$r4|BT$7$F$$$^$9!%%U%!%$%J%i%$%6<B9TCf$G$b!$6/@)E*$K%-%c%s%;%k$5$l$k(B $B$N$G!$2?$+8e=hM}$r$7$F$$$k:GCf$K;_$a$i$l$k$N$OIT2DHr$G$9!%(B # $B:#$^$GJ86g$,L5$+$C$?$H$$$&$N$O!$3NN(E*$K$3$&$$$&%1!<%9$,5/$-$E$i$$!$(B # $B$H$$$&$3$H$G$7$g$&$+$M!%(B $B!!??LLL\$K$d$k$J$i!$$9$G$K2?EY$+Ds0F$,$"$k!$$3$&$$$&3d$j9~$_$r@)8f$9$k$?(B $B$a$N;EAH$_$rE}0lE*$K@0Hw$9$k$C$F$3$H$K$J$k$H;W$$$^$9!%$&!<$s!$$;$a$F%U%!(B $B%$%J%i%$%6$N=hM}$O(B main thread $B$N$_$G9T$&$h$&$K$7$?$[$&$,$$$$$s$@$m$&$+!%(B $B!!$b$7$/$O!$$3$&$$$&=hM}$r9T$&$3$H$,$"$k$N$J$i!$$A$c$s$H(B join $B$7$F$+$i;`(B $B$K$^$7$g$&!$$H3+$-D>$C$F!$:G=i$N$4Ds0F$NDL$j!$3N<B$K;&$9!$$H$$$&$U$&$K?6(B $B$k$N$+$J$!!%$=$l$O$=$l$GITJX$=$&$K;W$&$N$@$1$I!%(B $B!!7kO@$b=P$F$^$;$s$,!$8=>u$O$J$s$H$J$/$&$^$/F0$/$3$H$,B?$$!$2~A1$9$k$K$O(B $B$7$s$I$=$&!$$H$$$&$3$H$G!$$J$s$H$J$/8=>u$N;EMM$K$J$C$F$$$k!$$H$$$&$3$H$+(B $B$H;W$$$^$9!%(B $B!!$b$7$&$^$$<j$,$"$l$P65$($F$/$@$5$$!%(B
on 2011-09-29 13:21
$B$J$+$@$G$9!#(B At Mon, 26 Sep 2011 23:52:19 +0900, SASADA Koichi wrote in [ruby-dev:44552]: > (2011/09/26 7:03), m_takao wrote: >> $B$3$l$O!V(Bensure$B@a$N<B9TCf$K;_$a$k$N$O(BNG$B!W$H$$$&$3$H$G$9$h$M(B? >> $B$$$^$N<BAu(B (rev.33339) $B$G$O!"(Bensure$B@a$N<B9TCf$G$"$C$F$b!"(Bterminate$B$5$l$?$i(B >> ($B30B&$K$5$i$J$k(Bensure$B@a$,$J$1$l$P(B) $B$U$D$&$K=*N;$9$k$N$G!"DTjm$,9g$o$J$$5$$,$7$^$9!#(B > > $B!!$4;XE&$NDL$j!$!V:G=i$N(B1$B2s$@$1$OI,$:(B ensure $BCf$G$b6/@)E*$K;_$a$F$7$^(B > $B$&!W$H$$$&;EMM$K$J$C$F$$$^$9$M!%8=>u$G$O!$(Bensure $BCf!J8e=hM}Cf!K$G$O$J$$(B > $B$3$H$r4|BT$7$F$$$^$9!%%U%!%$%J%i%$%6<B9TCf$G$b!$6/@)E*$K%-%c%s%;%k$5$l$k(B > $B$N$G!$2?$+8e=hM}$r$7$F$$$k:GCf$K;_$a$i$l$k$N$OIT2DHr$G$9!%(B ensure$B$G(Bsleep$B$5$l$?$i;_$^$k$N$O;EJ}$,$J$$$K$;$h!"$=$3$G3d$j9~$_$r<u$1$?(B $B$i$d$O$jH4$1$k$[$&$,$$$$$N$G$O$J$$$G$7$g$&$+!#(B diff --git i/thread.c w/thread.c index d9d497a..0e3d096 100644 --- i/thread.c +++ w/thread.c @@ -333,6 +333,7 @@ typedef struct rb_mutex_struct static void rb_mutex_abandon_all(rb_mutex_t *mutexes); static const char* rb_mutex_unlock_th(rb_mutex_t *mutex, rb_thread_t volatile *th); +static int vm_living_thread_num(rb_vm_t *vm); void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th) @@ -369,14 +370,20 @@ rb_thread_terminate_all(void) st_foreach(vm->living_threads, terminate_i, (st_data_t)th); vm->inhibit_thread_creation = 1; - while (!rb_thread_alone()) { + + if (th->vm->living_threads && vm_living_thread_num(th->vm) > 1) { + int state; + const double sleep_time = 3600.0; /* should not be too long to + * get rid of overflow */ PUSH_TAG(); - if (EXEC_TAG() == 0) { - rb_thread_schedule(); - } - else { - /* ignore exception */ + state = EXEC_TAG(); + while (state == 0 || !rb_thread_alone()) { + if (state) { + st_foreach(vm->living_threads, terminate_i, (st_data_t)th); + } + sleep_wait_for_interrupt(th, sleep_time); } + /* ignore exception */ POP_TAG(); } } @@ -445,6 +452,8 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s gvl_acquire(th->vm, th); { + int terminating = 0; + thread_debug("thread start (get lock): %p\n", (void *)th); rb_thread_set_current(th); @@ -469,6 +478,7 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s if (NIL_P(errinfo)) errinfo = rb_errinfo(); if (state == TAG_FATAL) { /* fatal error within this thread, need to stop whole script */ + terminating = (errinfo == eTerminateSignal); } else if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) { if (th->safe_level >= 4) { @@ -509,13 +519,23 @@ thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_s /* delete self other than main thread from living_threads */ if (th != main_th) { st_delete_wrap(th->vm->living_threads, th->self); + if (terminating) { + if (vm_living_thread_num(th->vm) == 1) { + rb_threadptr_interrupt(main_th); + } + else { + terminating = 0; + } + } } /* wake up joining threads */ join_th = th->join_list_head; while (join_th) { - if (join_th == main_th) errinfo = Qnil; - rb_threadptr_interrupt(join_th); + if ((join_th != main_th) || (errinfo = Qnil, !terminating)) { + /* main thread is already interrupted when terminating */ + rb_threadptr_interrupt(join_th); + } switch (join_th->status) { case THREAD_STOPPED: case THREAD_STOPPED_FOREVER: join_th->status = THREAD_RUNNABLE;
on 2011-09-29 14:15
2011$BG/(B9$B7n(B29$BF|(B20:20 Nobuyoshi Nakada <nobu@ruby-lang.org>: >> $B$&!W$H$$$&;EMM$K$J$C$F$$$^$9$M!%8=>u$G$O!$(Bensure $BCf!J8e=hM}Cf!K$G$O$J$$(B >> $B$3$H$r4|BT$7$F$$$^$9!%%U%!%$%J%i%$%6<B9TCf$G$b!$6/@)E*$K%-%c%s%;%k$5$l$k(B >> $B$N$G!$2?$+8e=hM}$r$7$F$$$k:GCf$K;_$a$i$l$k$N$OIT2DHr$G$9!%(B > > ensure$B$G(Bsleep$B$5$l$?$i;_$^$k$N$O;EJ}$,$J$$$K$;$h!"$=$3$G3d$j9~$_$r<u$1$?(B > $B$i$d$O$jH4$1$k$[$&$,$$$$$N$G$O$J$$$G$7$g$&$+!#(B $B8=:_$N(Bensure$BCf$NHsF14|Nc30$N07$$$O;EMM%P%0$G$"$k$H$$$&G'<1$J$N$G!"$3$&$$$&(B $B%o!<%/%"%i%&%s%I$K$O$"$^$j$$$$0u>]$r;}$A$^$;$s!#(B $B<BMQE*$K$bLdBj$,$"$k$H;W$C$F$$$F!"(BC-c $B$rF|>oE*$K#2!]#32sO"BG$9$kJJ$N$"$k$R$H$O(B $B$$$k$N$G!"$=$&$$$&?M$+$i$9$k$H%W%m%;%9=*N;=hM}$,$A$c$s$H9T$o$l$J$/$J$k(Bregression $B$K8+$($k$N$G$O$J$$$G$7$g$&$+!#(B
on 2011-09-29 18:32
Issue #5368 has been updated by Shyouhei Urabe. 提案されている workaround はいまいち、という点には同意します。 ただ、じゃあどうなるべきなの? というところのコンセンサスは足りていないでしょう。 というわけで結論を急がずに少し議論したほうがいいんじゃないでしょうか。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない http://redmine.ruby-lang.org/issues/5368 Author: Masaki Matsushita Status: Open Priority: Normal Assignee: Category: core Target version: 1.9.x 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
on 2012-03-11 08:06
Issue #5368 has been updated by Koichi Sasada. Assignee set to Koichi Sasada 今日,非同期例外の話が出たので,それと交えて考えます. 多分. ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368 Author: Masaki Matsushita Status: Open Priority: Normal Assignee: Koichi Sasada 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
on 2012-11-26 01:44
Issue #5368 has been updated by ko1 (Koichi Sasada). Assignee changed from ko1 (Koichi Sasada) to kosaki (Motohiro KOSAKI) Priority changed from Normal to High ticket の詳細が思い出せないので小崎先生に振ってみます. control_interrupt じゃ解決しないんだよな,多分. ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33915 Author: Glass_saga (Masaki Matsushita) Status: Assigned Priority: High Assignee: kosaki (Motohiro KOSAKI) 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
on 2012-11-26 04:27
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). 読み返しました。[Feature #1952] とちょっと似た話で終了途中で例外食われてしまったら、という話のようですね。論点をまとめると - ensure節の中でsleep等、無限待ちが記述されているとハングしてしまう。これはバグではないか (Glass_saga) - この場合止まっているのはサブスレッドなので、Ctrl-cは意味が無い。メインスレッドが食って無視してしまう - しかし、タイムアウト等をつくると終了処理に時間のかかるスクリプトが壊れてしまう (ko1) - ensure節実行中にterminateされたらensure抜けてしまうので言語仕様としてつじつまがあってない (高尾さん) - sleepで寝ていても、もう一度例外が上がってきたら抜けるべきでは? (← これよくわからないが Ctrl-Cうけたらメインスレッドがthread terminateを再送しろということ?) - Ctrl-c 二連打で、終了処理がスッポ抜けるのって本当にうれしい?(こさき) - 現在、main threadがsub threadの終了を待つロジックがビジーループなのでCPU100%になってしまう。スレッドが終了するまでちゃんと寝るべきではないのか (やや脱線) ぐらいですかね。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33934 Author: Glass_saga (Masaki Matsushita) Status: Assigned Priority: High Assignee: kosaki (Motohiro KOSAKI) 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
on 2012-11-26 14:41
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). なお、#1952 ですでに指摘されているように Ctrl-c が押された時にサブスレッドを待たずに終了してしまうという案はSEGVを引き起こすのでNG。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33957 Author: Glass_saga (Masaki Matsushita) Status: Assigned Priority: High Assignee: kosaki (Motohiro KOSAKI) 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
on 2012-11-26 15:00
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さんが選択肢をいくつか列挙してくれていて > 捕捉できない例外を投げる > - サブスレッドの 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
on 2012-11-26 17:16
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). 1.8 だと、Ctrl-C でsleepを抜けてくれるようです。うーん、この挙動のほうがいいんかなあ。1.8がどういう理屈でこう動いているのかよくわからないんだけど、ようするにInterruptがmain threadではなく、たまたまその時動いていたThreadに飛ぶようなシロモノだったということだろうか(推測) ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33966 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
on 2012-11-26 17:26
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). % Done changed from 100 to 50 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33967 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
on 2012-11-26 21:12
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
on 2012-11-27 00:14
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). [Feature #1952]の対策として、r37875でCtrl-Cが押されるたびに eTerminateSignalを最送出するようにしたので、現状1.8と同等の動きをするようになってます。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-33988 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
on 2012-11-27 00:17
Issue #5368 has been updated by kosaki (Motohiro KOSAKI).
1.8と同等と書いたのは
Thread.new do
begin
sleep
ensure
sleep
end
end
というプログラムが一度ensure節のsleepで寝てしまうが、Ctrl-Cにより終わることは出来る。という挙動を指しており、
このスクリプト以外の細かい挙動について、不整合はあると思います。
----------------------------------------
Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない
https://bugs.ruby-lang.org/issues/5368#change-33990
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
on 2012-11-27 18:08
Issue #5368 has been updated by kosaki (Motohiro KOSAKI). > なお、#1952 ですでに指摘されているように Ctrl-c が押された時にサブスレッドを待たずに終了してしまうという案はSEGVを引き起こすのでNG。 もうちょっとまじめに書くと、SEGVを引き起こすのは終了処理でまじめに1つ1つリソース解放処理をしてるからで、いきなりexit()するという選択肢はあるだろう。しかしそれは当然MVMにしたときに問題を引き起こす。 SEGVしないように各所にNULLチェックを入れるという案については、pthread_cond_destruct()が別スレッドがリソース使用中に呼び出されるとEBUSYで失敗するためうまくいかない ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-34052 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
on 2013-02-17 07:26
Issue #5368 has been updated by ko1 (Koichi Sasada). Assignee changed from matz (Yukihiro Matsumoto) to kosaki (Motohiro KOSAKI) Target version changed from 2.0.0 to 2.1.0 2.1 で結論を付けたいところ。 多分、まつもとさんはこの辺気にしないと思うので、小崎さん、たるいさん(と私かなぁ)で決めると良いと思います。 ---------------------------------------- Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない https://bugs.ruby-lang.org/issues/5368#change-36400 Author: Glass_saga (Masaki Matsushita) Status: Assigned Priority: Normal Assignee: kosaki (Motohiro KOSAKI) Category: core Target version: 2.1.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
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.