From: Masahiro Sakai (=?iso-2022-jp?B?GyRCPHIwZkAvTTUbKEI=?=) Date: 2004-05-26T00:25:33+09:00 Subject: [ruby-dev:23619] Timeout and ConditionVariable#wait さかいといいます Timeout#timeout内でConditionVariable#waitを実行しタイムアウトになると、 Mutexがunlockされたままになってしまいます。 require 'timeout' require 'thread' mutex = Mutex.new resource = ConditionVariable.new mutex.synchronize{ begin timeout(0.01){ resource.wait(mutex) } rescue Timeout::Error p mutex.locked? #=> false end } # そもそも、この2つを組み合わせるのが想定外なのかもしれませんが、 # 幾つかのスレッドライブラリ (e.g. pthread, gthread, SRFI-18, Win32, etc) では # timeoutを指定してwaitすることが出来るので、 # Rubyのスレッドでも同じことをしたかったのです。 最初は以下のように単にbegin/ensureを使うよう変更すればよいのかと思ったのですが、 ensure節まで到達した後 mutex.lock を実行する直前のタイミングで Timeoutによって割り込まれる可能性も考慮する必要があるのでしょうか…… Index: lib/thread.rb =================================================================== RCS file: /src/ruby/lib/thread.rb,v retrieving revision 1.16 diff -u -p -r1.16 thread.rb --- lib/thread.rb 16 Nov 2003 01:53:12 -0000 1.16 +++ lib/thread.rb 25 May 2004 14:16:00 -0000 @@ -189,11 +189,14 @@ class ConditionVariable # Releases the lock held in +mutex+ and waits; reacquires the lock on wakeup. # def wait(mutex) - mutex.exclusive_unlock do - @waiters.push(Thread.current) - Thread.stop + begin + mutex.exclusive_unlock do + @waiters.push(Thread.current) + Thread.stop + end + ensure + mutex.lock end - mutex.lock end # -- 酒井 政裕 / Masahiro Sakai