原です。
せきさん、お世話になっています。まだ erb.rb とスレッドの絡む話
についていっていません。(すいません、引越しで忙しくて。(^^;)
In message "[ruby-list:14445] Re: ConditionVariable (thread.rb)"
on 99/05/24, SEKI <m_seki / mva.biglobe.ne.jp> writes:
|
|咳です。
|
|:ConditionVariable のwaitメソッドの引数 mutex は
|:どう使えばよいのでしょうか?
|:なにかサンプルスクリプトはないでしょうか?
|
|こんな感じでしょうか?
|class TinyQueue
これ、いいと思います。
# synchronize を使わないのは何か理由があるんですか?
前に、ほぼ同様なものを [ruby-list:6794] に前田さんが書いて
います。当時の ConditionVariable の仕様はちょっと違いますが。
[ruby-list:6735] から始まるスレッドは読み難くてというか、そ
もそもスレッドって難しくて往生します。
ConditionVariable#wait(mutex) ってのも分かりにくいですね。
この mutex ってロックするために渡すのではなく、一時的に解
放してもらうためにあるんですね。
ところでなんでこんな仕様になっているんですかね。そもそも
wait とか stop とかは dead lock になる可能性があるので、
必ず注意が必要なのだから、むしろその部分はユーザーまかせ
ていいのではないでしょうか。わざわざ指定するのは注意の喚
起のため?
こういう案はどうでしょうか。
Mutex に一時的なロックの解除するメソッドを指定する。
class Mutex
def release
unlock
yield
lock
end
end
で、ConditionVariable#wait の引数はなし(あるいはオプション)にする。
class ConditionVariable
def wait
@waiters_mutex.synchronize {
@waiters.push(Thread.current)
}
Thread.stop
end
end
で、こうすると
def enq(v)
@mutex.synchronize {
@full.wait(@mutex) if count == @max
@q.push v
@empty.signal if count == 1
}
end
と書く所を
def enq(v)
@mutex.synchronize {
@mutex.release {
@full.wait if count == @max
}
@q.push v
@empty.signal if count == 1
}
end
と書くようになる。
この方が何をしているか、どんな危険があるかはっきりして見通
しがよくなりますよね。wait を synchronize の外に出しても同
値であることなどが見えるし。