前田です。

At Mon, 7 Jun 1999 01:44:26 +0900,
Shin-ichiro Hara <sinara / blade.nagaokaut.ac.jp> wrote:
> > で、ここでwakeupしているのは、クリティカルセクションではrunしても
> > スケジューリングイベントは起きないからです。
> > # つまり、runでも同じだけど意味がないのでwakeupにしているわけです。
> 
> Thread.critical == true では Thread.pass も Thread#run もスレッド
> のスイッチは起こらないのですね。いままでそういうことをやってみた
> ことがなかったので知りませんでした。(~~;

この辺はそもそもドキュメントがないので動作を知りたかったらソース
読むしかないですからね(^_^;

> > t.run
> > 
> > というのは、
> > 
> > t.wakeup
> > Thread.pass
> > 
> > と同値なので、t.runした直後にtに実行権が渡ることは必ずしも保証さ
> > れないような気がして、このようにしてあります。
> > # ひょっとして保証されるんですか?>まつもとさん
> > 
> > つまりrunでも問題が起きる可能性はあるのではないかと。
> 
> ええっ、そうなんですか?いやっ、きっとそうなんですね。
> 
> 考えてみると Thread.stop; X; で止まったスレッドを他から run で起こし
> ても X がアトミックでない限り X が実行されるとはいえないですものね。
> 例えば X が Thread.critical=true だとすると true を評価したあと、
> critical= を実行する前にスイッチしてしまうかもしれない。(あるいは
> "Thread" を評価した直後にスイッチするかも。)と、いうことは、次に確
> 実に特定のスレッドを動かすという事を考えること自体、あまり意味がな
> いといえる。

その例はちょっと極端ですが(^_^;、ユーザレベルのプログラミングであ
まりスケジューリングを制御しようとするべきではないというのは確か
にそうですよね。
ただ、今回のはライブラリなので、ほんとはeval.cに手を入れてプライ
オリティを組込む方が良いのかもしれませんけど...。

> だいぶわかってきました。Ruby のスレッドは円形に並んでぐるぐる回っ
> ているわけですね。
> 
> 肝要なのは signal 後、条件を他のスレッドに変更されない事では
> なく、signal の後は(1周以上したとしても)必ず、しかも早めに
> wait のスレッドにロックが戻る事ですね。

そうです。
ロックさえ獲得できれば他のスレッドを気にしなくてよいですからね。

> 結局、私のあの単純な CV のコード(cv2.rb)、あれはあれでちゃん
> と動くんですよね。

競合する(条件を偽にしようとする)スレッドにロックを横取りされる可
能性はあります。
ただ、私のコードでも、競合するスレッドで、

1000.times do
  break if m.try_lock
  Thread.pass
end

などとされるとだめですね。
防ぐ手はある(フラグを一個追加すればいいのかな)と思うのですが、そ
こまでするとコードがどんどん見にくくなっていくのであまりやりたく
ないような気もします。

-- 
前田 修吾