From: "kosaki (Motohiro KOSAKI)" Date: 2012-11-28T22:47:49+09:00 Subject: [ruby-dev:46655] [ruby-trunk - Bug #7455] Queue#popで待っている間にtrapに入りその時にQueue#pushされると、Queue#popから戻ってこなくなる。 Issue #7455 has been updated by kosaki (Motohiro KOSAKI). とりあえず原因を書いておくと 1. que.popで、mutex.sleepが呼ばれ、結局sleep_forever()が呼ばれる。ここで一旦 status = THREAD_STOPPED_FOREVERになる 2. Process.kill をうけて status = THREAD_RUNNABLEにしてトラップハンドラを実行はじめる 3. que.push を呼ぶが、main threadはすでに thread runnableなので何もおこらず 4. サブスレッド死ぬ 5. trap抜けたところで rb_threadptr_execute_interrupt()内の th->status = prev_status; の処理によって、 statusがTHREAD_STOPPED_FOREVERに戻る 6.sleep_forever() は status != THREAD_RUNNABLE の場合sleepを再実行するので、ここでデッドロックチェック 唯一残っているスレッドであるメインスレッドが THREAD_STOPPED_FOREVERなので、めでたくチェックにひっかかり強制終了 ささださん、よろしく ---------------------------------------- Bug #7455: Queue#popで待っている間にtrapに入りその時にQueue#pushされると、Queue#popから戻ってこなくなる。 https://bugs.ruby-lang.org/issues/7455#change-34084 Author: tarui (Masaya Tarui) Status: Assigned Priority: Normal Assignee: ko1 (Koichi Sasada) Category: core Target version: 2.0.0 ruby -v: ruby 2.0.0dev (2012-11-28 trunk 37937) [x86_64-linux] 以下スクリプトを実行すると期待したように終わらずに、deadlockしてしまいます。 ささださんよろしく。 -- require 'thread' que = Queue.new th = Thread.new{ sleep 0.1 Process.kill(:INT,$$) sleep 0.1 que.push 2 } Signal.trap :INT do p :trap_task 123456**100000 / 456 ** 10000 p :trap_task_end end puts "que.pop" p que.pop puts "success!" -- http://bugs.ruby-lang.org/