Project

General

Profile

Feature #3251

Updated by ko1 (Koichi Sasada) over 6 years ago

=begin

遠藤です。

現状では mutex は lock したスレッドからしか unlock できませんが、
これを許可するようにしませんか。動機は 2 つあります。

1) Python の condition variable が mutex を別スレッドから unlock
することで実装されている、のが真似できる
2) Thread#raise を race condition なしに使えるようになる (気がする)


1 について、Python の condition variable は以下のような感じに実装
されています。

def wait(m1)
m2 = Mutex.new
m2.lock
@waiters << m2
m1.unlock
begin
m2.lock
ensure
m1.lock
end
end

def signal
@waiters.shift.unlock
end

つまり、wait は二重に mutex を lock しようとすることでブロックし、
signal は mutex を別スレッドから unlock することでブロックしている
スレッドを再開します。
今の ConditionVariable の実装には大量の問題点が指摘されているので、
Python の真似をするとよいのではと思います。

# 権威主義


2 について、現状は Thread#raise には以下のような race が存在します。

t1: begin 節を実行している
t2: t1.raise する
t1: rescue/ensure 節の実行を開始する
t3: t1.raise する
t1: rescue/ensure 節が実行されないまま再度例外が発生する

# ちなみにこの race はシグナルにも存在します

これを、Thread#raise の前に Mutex#lock するというルールにすれば、
race を避けて使うことができるようになります。と思います。

t1: begin 節を実行している
t2: m.lock; t1.raise する
t1: rescue/ensure 節の実行を開始する
t3: m.lock が止まらないので t1.raise できない
t1: 次の例外が投げ込まれる準備ができたら m.unlock する
t3: m.lock が終わって t1.raise する

--
Yusuke Endoh <mame@tsg.ne.jp>

=end

Back