ruby-dev (Japanese) list archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
@ 2011-09-26  4:51 Masaki Matsushita
  2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
                   ` (15 more replies)
  0 siblings, 16 replies; 22+ messages in thread
From: Masaki Matsushita @ 2011-09-26  4:51 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://redmine.ruby-lang.org

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44547] Re: [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
@ 2011-09-26  5:24 ` SASADA Koichi
  2011-09-26 13:40   ` [ruby-dev:44550] " KOSAKI Motohiro
  2011-09-26 14:03   ` [ruby-dev:44551] " m_takao
  2011-09-29 16:29 ` [ruby-dev:44564] [Ruby 1.9 - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Shyouhei Urabe
                   ` (14 subsequent siblings)
  15 siblings, 2 replies; 22+ messages in thread
From: SASADA Koichi @ 2011-09-26  5:24 UTC (permalink / raw)
  To: ruby developers list

(2011/09/25 21:51), Masaki Matsushita wrote:
> 次のコードを実行すると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())が無限ループになってしまいます。

 ここで,バグとは何でしょうか.

(1) CPU 使用率がはねあがる
(2) プロセスが死なない


 (1) が問題というのは理解できます.あまり文句がないんで放置している部分
です.直そうと思えば,正しく他のスレッドを待ち合わせをすればできると思っ
ています.

 (2) については仕様です.ご提案の修正方法では,とにかく生きていたら殺
す,ということをしていますが,例えば他のスレッドで何か時間のかかる終了処
理をしていた場合(例えば,終了時にネットワークで外部に情報を送る,という
ようなことをしている場合),それを強制的に止めてしまうため,まずいことに
なります.

 ということで,これに関しては,現状だと仕様かな,と思いますが,もっと良
い仕様があれば,ご提案頂けと助かります.

-- 
// SASADA Koichi at atdot dot net

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44550] Re: [Ruby 1.9 - Bug #5368][Open]  ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
@ 2011-09-26 13:40   ` KOSAKI Motohiro
  2011-09-26 14:03   ` [ruby-dev:44551] " m_takao
  1 sibling, 0 replies; 22+ messages in thread
From: KOSAKI Motohiro @ 2011-09-26 13:40 UTC (permalink / raw)
  To: ruby developers list

2011年9月26日14:24 SASADA Koichi <ko1@atdot•net>:
> (2011/09/25 21:51), Masaki Matsushita wrote:
>> 次のコードを実行すると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())が無限ループになってしまいます。
>
>  ここで,バグとは何でしょうか.
>
> (1) CPU 使用率がはねあがる
> (2) プロセスが死なない
>
>  (1) が問題というのは理解できます.あまり文句がないんで放置している部分
> です.直そうと思えば,正しく他のスレッドを待ち合わせをすればできると思っ
> ています.
>
>  (2) については仕様です.ご提案の修正方法では,とにかく生きていたら殺
> す,ということをしていますが,例えば他のスレッドで何か時間のかかる終了処
> 理をしていた場合(例えば,終了時にネットワークで外部に情報を送る,という
> ようなことをしている場合),それを強制的に止めてしまうため,まずいことに
> なります.
>
>  ということで,これに関しては,現状だと仕様かな,と思いますが,もっと良
> い仕様があれば,ご提案頂けと助かります.

C言語だってat_exit()でsleep()したら死なないし、C++だってデストラクタでsleep()したら
死なないしねえ。
プログラミング言語はアホなコードにたいしてアホな振る舞いをするのはそういうものという気がします。個人的には。

ensureにsleepを書くことが避けることが不可能。という話になるとまたちょっと話が変わってくるかと
思いますが、そういう例は思いつきませんでした。

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44551] Re: [Ruby 1.9 - Bug #5368][Open]  ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
  2011-09-26 13:40   ` [ruby-dev:44550] " KOSAKI Motohiro
@ 2011-09-26 14:03   ` m_takao
  2011-09-26 14:52     ` [ruby-dev:44552] " SASADA Koichi
  1 sibling, 1 reply; 22+ messages in thread
From: m_takao @ 2011-09-26 14:03 UTC (permalink / raw)
  To: ruby developers list

高尾と申します。

>  (2) については仕様です.ご提案の修正方法では,とにかく生きていたら殺
> す,ということをしていますが,例えば他のスレッドで何か時間のかかる終了処
> 理をしていた場合(例えば,終了時にネットワークで外部に情報を送る,という
> ようなことをしている場合),それを強制的に止めてしまうため,まずいことに
> なります.

これは「ensure節の実行中に止めるのはNG」ということですよね?
いまの実装 (rev.33339) では、ensure節の実行中であっても、terminateされたら
(外側にさらなるensure節がなければ) ふつうに終了するので、辻褄が合わない気がします。

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44552] Re: [Ruby 1.9 - Bug #5368][Open]  ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26 14:03   ` [ruby-dev:44551] " m_takao
@ 2011-09-26 14:52     ` SASADA Koichi
  2011-09-29 11:20       ` [ruby-dev:44561] " Nobuyoshi Nakada
  0 siblings, 1 reply; 22+ messages in thread
From: SASADA Koichi @ 2011-09-26 14:52 UTC (permalink / raw)
  To: ruby developers list

(2011/09/26 7:03), m_takao wrote:
> これは「ensure節の実行中に止めるのはNG」ということですよね?
> いまの実装 (rev.33339) では、ensure節の実行中であっても、terminateされたら
> (外側にさらなるensure節がなければ) ふつうに終了するので、辻褄が合わない気がします。

 ご指摘の通り,「最初の1回だけは必ず ensure 中でも強制的に止めてしま
う」という仕様になっていますね.現状では,ensure 中(後処理中)ではない
ことを期待しています.ファイナライザ実行中でも,強制的にキャンセルされる
ので,何か後処理をしている最中に止められるのは不可避です.

# 今まで文句が無かったというのは,確率的にこういうケースが起きづらい,
# ということでしょうかね.

 真面目にやるなら,すでに何度か提案がある,こういう割り込みを制御するた
めの仕組みを統一的に整備するってことになると思います.うーん,せめてファ
イナライザの処理は main thread のみで行うようにしたほうがいいんだろうか.

 もしくは,こういう処理を行うことがあるのなら,ちゃんと join してから死
にましょう,と開き直って,最初のご提案の通り,確実に殺す,というふうに振
るのかなぁ.それはそれで不便そうに思うのだけど.

 結論も出てませんが,現状はなんとなくうまく動くことが多い,改善するには
しんどそう,ということで,なんとなく現状の仕様になっている,ということか
と思います.

 もしうまい手があれば教えてください.

-- 
// SASADA Koichi at atdot dot net

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44561] Re: [Ruby 1.9 - Bug #5368][Open]  ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26 14:52     ` [ruby-dev:44552] " SASADA Koichi
@ 2011-09-29 11:20       ` Nobuyoshi Nakada
  2011-09-29 12:14         ` [ruby-dev:44563] " KOSAKI Motohiro
  0 siblings, 1 reply; 22+ messages in thread
From: Nobuyoshi Nakada @ 2011-09-29 11:20 UTC (permalink / raw)
  To: ruby developers list

なかだです。

At Mon, 26 Sep 2011 23:52:19 +0900,
SASADA Koichi wrote in [ruby-dev:44552]:
> (2011/09/26 7:03), m_takao wrote:
>> これは「ensure節の実行中に止めるのはNG」ということですよね?
>> いまの実装 (rev.33339) では、ensure節の実行中であっても、terminateされたら
>> (外側にさらなるensure節がなければ) ふつうに終了するので、辻褄が合わない気がします。
> 
>  ご指摘の通り,「最初の1回だけは必ず ensure 中でも強制的に止めてしま
> う」という仕様になっていますね.現状では,ensure 中(後処理中)ではない
> ことを期待しています.ファイナライザ実行中でも,強制的にキャンセルされる
> ので,何か後処理をしている最中に止められるのは不可避です.

ensureでsleepされたら止まるのは仕方がないにせよ、そこで割り込みを受けた
らやはり抜けるほうがいいのではないでしょうか。

\f
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;
\f

-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [ruby-dev:44563] Re: [Ruby 1.9 - Bug #5368][Open]  ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-29 11:20       ` [ruby-dev:44561] " Nobuyoshi Nakada
@ 2011-09-29 12:14         ` KOSAKI Motohiro
  0 siblings, 0 replies; 22+ messages in thread
From: KOSAKI Motohiro @ 2011-09-29 12:14 UTC (permalink / raw)
  To: ruby developers list

2011年9月29日20:20 Nobuyoshi Nakada <nobu@ruby-lang.org>:
> なかだです。
>
> At Mon, 26 Sep 2011 23:52:19 +0900,
> SASADA Koichi wrote in [ruby-dev:44552]:
>> (2011/09/26 7:03), m_takao wrote:
>>> これは「ensure節の実行中に止めるのはNG」ということですよね?
>>> いまの実装 (rev.33339) では、ensure節の実行中であっても、terminateされたら
>>> (外側にさらなるensure節がなければ) ふつうに終了するので、辻褄が合わない気がします。
>>
>>  ご指摘の通り,「最初の1回だけは必ず ensure 中でも強制的に止めてしま
>> う」という仕様になっていますね.現状では,ensure 中(後処理中)ではない
>> ことを期待しています.ファイナライザ実行中でも,強制的にキャンセルされる
>> ので,何か後処理をしている最中に止められるのは不可避です.
>
> ensureでsleepされたら止まるのは仕方がないにせよ、そこで割り込みを受けた
> らやはり抜けるほうがいいのではないでしょうか。

現在のensure中の非同期例外の扱いは仕様バグであるという認識なので、こういう
ワークアラウンドにはあまりいい印象を持ちません。
実用的にも問題があると思っていて、C-c を日常的に2−3回連打する癖のあるひとは
いるので、そういう人からするとプロセス終了処理がちゃんと行われなくなるregression
に見えるのではないでしょうか。

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:44564] [Ruby 1.9 - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
  2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
@ 2011-09-29 16:29 ` Shyouhei Urabe
  2012-03-11  7:06 ` [ruby-dev:45327] [ruby-trunk " Koichi Sasada
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Shyouhei Urabe @ 2011-09-29 16:29 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://redmine.ruby-lang.org

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:45327] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
  2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
  2011-09-29 16:29 ` [ruby-dev:44564] [Ruby 1.9 - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Shyouhei Urabe
@ 2012-03-11  7:06 ` Koichi Sasada
  2012-11-26  0:26 ` [ruby-dev:46622] " ko1 (Koichi Sasada)
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: Koichi Sasada @ 2012-03-11  7:06 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46622] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (2 preceding siblings ...)
  2012-03-11  7:06 ` [ruby-dev:45327] [ruby-trunk " Koichi Sasada
@ 2012-11-26  0:26 ` ko1 (Koichi Sasada)
  2012-11-26  3:27 ` [ruby-dev:46626] " kosaki (Motohiro KOSAKI)
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: ko1 (Koichi Sasada) @ 2012-11-26  0:26 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46626] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (3 preceding siblings ...)
  2012-11-26  0:26 ` [ruby-dev:46622] " ko1 (Koichi Sasada)
@ 2012-11-26  3:27 ` kosaki (Motohiro KOSAKI)
  2012-11-26 13:40 ` [ruby-dev:46631] " kosaki (Motohiro KOSAKI)
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26  3:27 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46631] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (4 preceding siblings ...)
  2012-11-26  3:27 ` [ruby-dev:46626] " kosaki (Motohiro KOSAKI)
@ 2012-11-26 13:40 ` kosaki (Motohiro KOSAKI)
  2012-11-26 13:59 ` [ruby-dev:46632] [ruby-trunk - Bug #5368][Assigned] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 13:40 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46632] [ruby-trunk - Bug #5368][Assigned] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (5 preceding siblings ...)
  2012-11-26 13:40 ` [ruby-dev:46631] " kosaki (Motohiro KOSAKI)
@ 2012-11-26 13:59 ` kosaki (Motohiro KOSAKI)
  2012-11-26 16:15 ` [ruby-dev:46634] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 13:59 UTC (permalink / raw)
  To: ruby developers list


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/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46634] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (6 preceding siblings ...)
  2012-11-26 13:59 ` [ruby-dev:46632] [ruby-trunk - Bug #5368][Assigned] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
@ 2012-11-26 16:15 ` kosaki (Motohiro KOSAKI)
  2012-11-26 16:26 ` [ruby-dev:46635] " kosaki (Motohiro KOSAKI)
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 16:15 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46635] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (7 preceding siblings ...)
  2012-11-26 16:15 ` [ruby-dev:46634] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
@ 2012-11-26 16:26 ` kosaki (Motohiro KOSAKI)
  2012-11-26 20:09 ` [ruby-dev:46636] " tarui (Masaya Tarui)
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 16:26 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46636] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (8 preceding siblings ...)
  2012-11-26 16:26 ` [ruby-dev:46635] " kosaki (Motohiro KOSAKI)
@ 2012-11-26 20:09 ` tarui (Masaya Tarui)
  2012-11-26 23:13 ` [ruby-dev:46637] " kosaki (Motohiro KOSAKI)
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: tarui (Masaya Tarui) @ 2012-11-26 20:09 UTC (permalink / raw)
  To: ruby developers list


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/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46637] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (9 preceding siblings ...)
  2012-11-26 20:09 ` [ruby-dev:46636] " tarui (Masaya Tarui)
@ 2012-11-26 23:13 ` kosaki (Motohiro KOSAKI)
  2012-11-26 23:16 ` [ruby-dev:46638] " kosaki (Motohiro KOSAKI)
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 23:13 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46638] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (10 preceding siblings ...)
  2012-11-26 23:13 ` [ruby-dev:46637] " kosaki (Motohiro KOSAKI)
@ 2012-11-26 23:16 ` kosaki (Motohiro KOSAKI)
  2012-11-27 17:08 ` [ruby-dev:46643] " kosaki (Motohiro KOSAKI)
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-26 23:16 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:46643] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (11 preceding siblings ...)
  2012-11-26 23:16 ` [ruby-dev:46638] " kosaki (Motohiro KOSAKI)
@ 2012-11-27 17:08 ` kosaki (Motohiro KOSAKI)
  2013-02-17  6:19 ` [ruby-dev:47006] " ko1 (Koichi Sasada)
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 22+ messages in thread
From: kosaki (Motohiro KOSAKI) @ 2012-11-27 17:08 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:47006] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (12 preceding siblings ...)
  2012-11-27 17:08 ` [ruby-dev:46643] " kosaki (Motohiro KOSAKI)
@ 2013-02-17  6:19 ` ko1 (Koichi Sasada)
  2014-01-30  6:16 ` [ruby-dev:47929] " shibata.hiroshi
  2018-04-06  5:28 ` [ruby-dev:50521] [Ruby trunk Bug#5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない mame
  15 siblings, 0 replies; 22+ messages in thread
From: ko1 (Koichi Sasada) @ 2013-02-17  6:19 UTC (permalink / raw)
  To: ruby developers list


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


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:47929] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (13 preceding siblings ...)
  2013-02-17  6:19 ` [ruby-dev:47006] " ko1 (Koichi Sasada)
@ 2014-01-30  6:16 ` shibata.hiroshi
  2018-04-06  5:28 ` [ruby-dev:50521] [Ruby trunk Bug#5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない mame
  15 siblings, 0 replies; 22+ messages in thread
From: shibata.hiroshi @ 2014-01-30  6:16 UTC (permalink / raw)
  To: ruby-dev

Issue #5368 has been updated by Hiroshi SHIBATA.

Target version changed from 2.1.0 to current: 2.2.0

----------------------------------------
Bug #5368: ensure節でsleepするようなThreadがあるとインタプリタが終了しない
https://bugs.ruby-lang.org/issues/5368#change-44739

* Author: Masaki Matsushita
* Status: Assigned
* Priority: Normal
* Assignee: Motohiro KOSAKI
* Category: core
* Target version: current: 2.2.0
* 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)


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [ruby-dev:50521] [Ruby trunk Bug#5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない
  2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
                   ` (14 preceding siblings ...)
  2014-01-30  6:16 ` [ruby-dev:47929] " shibata.hiroshi
@ 2018-04-06  5:28 ` mame
  15 siblings, 0 replies; 22+ messages in thread
From: mame @ 2018-04-06  5:28 UTC (permalink / raw)
  To: ruby-dev

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/

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2018-04-06  5:28 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-26  4:51 [ruby-dev:44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Masaki Matsushita
2011-09-26  5:24 ` [ruby-dev:44547] " SASADA Koichi
2011-09-26 13:40   ` [ruby-dev:44550] " KOSAKI Motohiro
2011-09-26 14:03   ` [ruby-dev:44551] " m_takao
2011-09-26 14:52     ` [ruby-dev:44552] " SASADA Koichi
2011-09-29 11:20       ` [ruby-dev:44561] " Nobuyoshi Nakada
2011-09-29 12:14         ` [ruby-dev:44563] " KOSAKI Motohiro
2011-09-29 16:29 ` [ruby-dev:44564] [Ruby 1.9 - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない Shyouhei Urabe
2012-03-11  7:06 ` [ruby-dev:45327] [ruby-trunk " Koichi Sasada
2012-11-26  0:26 ` [ruby-dev:46622] " ko1 (Koichi Sasada)
2012-11-26  3:27 ` [ruby-dev:46626] " kosaki (Motohiro KOSAKI)
2012-11-26 13:40 ` [ruby-dev:46631] " kosaki (Motohiro KOSAKI)
2012-11-26 13:59 ` [ruby-dev:46632] [ruby-trunk - Bug #5368][Assigned] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
2012-11-26 16:15 ` [ruby-dev:46634] [ruby-trunk - Bug #5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない kosaki (Motohiro KOSAKI)
2012-11-26 16:26 ` [ruby-dev:46635] " kosaki (Motohiro KOSAKI)
2012-11-26 20:09 ` [ruby-dev:46636] " tarui (Masaya Tarui)
2012-11-26 23:13 ` [ruby-dev:46637] " kosaki (Motohiro KOSAKI)
2012-11-26 23:16 ` [ruby-dev:46638] " kosaki (Motohiro KOSAKI)
2012-11-27 17:08 ` [ruby-dev:46643] " kosaki (Motohiro KOSAKI)
2013-02-17  6:19 ` [ruby-dev:47006] " ko1 (Koichi Sasada)
2014-01-30  6:16 ` [ruby-dev:47929] " shibata.hiroshi
2018-04-06  5:28 ` [ruby-dev:50521] [Ruby trunk Bug#5368] ensure節でsleepするようなThreadがあるとインタプリタが終了しない mame

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).