原です。

> 前田です。

> で、ここでwakeupしているのは、クリティカルセクションではrunしても
> スケジューリングイベントは起きないからです。
> # つまり、runでも同じだけど意味がないのでwakeupにしているわけです。

Thread.critical == true では Thread.pass も Thread#run もスレッド
のスイッチは起こらないのですね。いままでそういうことをやってみた
ことがなかったので知りませんでした。(~~;

> > ええ、そうなっているのはわかります。しかしそんなことが必要になっ
> > てしまうのは signal で run させずに wakeup させているからですよ
> > ね。私の cv2.rb みたいに run させればいいだけのことではないかな
> > あ。なぜ run させずに wakeup & pass させるのだろう。
> 
> t.run
> 
> というのは、
> 
> t.wakeup
> Thread.pass
> 
> と同値なので、t.runした直後にtに実行権が渡ることは必ずしも保証さ
> れないような気がして、このようにしてあります。
> # ひょっとして保証されるんですか?>まつもとさん
> 
> つまりrunでも問題が起きる可能性はあるのではないかと。

ええっ、そうなんですか?いやっ、きっとそうなんですね。

考えてみると Thread.stop; X; で止まったスレッドを他から run で起こし
ても X がアトミックでない限り X が実行されるとはいえないですものね。
例えば X が Thread.critical=true だとすると true を評価したあと、
critical= を実行する前にスイッチしてしまうかもしれない。(あるいは
"Thread" を評価した直後にスイッチするかも。)と、いうことは、次に確
実に特定のスレッドを動かすという事を考えること自体、あまり意味がな
いといえる。

#いや、特定のスレッド以外すべて止めて自分も止まって処理を渡す
#という方法もあるにはあるけど。


> > |あと、wakeupを使っているのはスケジューリングが起こって欲しくない
> > |からですね。
> > 
> > ああ、ここでスケジューリングというのはスレッドのスイッチという意味
> > ですね。なぜスイッチしたらいかんのだろう。どうせ不定な時期にスイッ
> > チするんだからここで意図してスイッチを起こしてもいいようが気がする
> > のですが。

> で、ここでwakeupしているのは、クリティカルセクションではrunしても
> スケジューリングイベントは起きないからです。
> # つまり、runでも同じだけど意味がないのでwakeupにしているわけです。

ここをクリティカルセクションにするのをやめて、run させたらどうかという
つもりだったのですが、この提案は今やナンセンスか。(~~;;

> > もしそういうことなら、signal の頭で Thread.critical の値を保存し
> > て、最後にそれを復活させる(そして Thread.pass もさせない)という
> > のが徹底していて、いい様な気もします。

クリティカルセクションでは pass もできないのですね。とにかくこの
提案は(またまた)見なかった事に。(^^;;


> いや、ここはスケジューリングイベントを起こさないといけないんです。
> というのは、signalしたスレッドがまだロックを保持している間に、
> waitしているスレッドにスイッチしておかないと、せっかくキューに優
> 先順位を設けたのに、キューに並ぶひまもなく、他のスレッドにロック
> を奪われてしまうかもしれないからです。
> signalしたスレッドがまだロックを保持している間は、他のスレッドに
> 実行が渡ってもキューの優先順位があるので大丈夫なのですが、ロック
> がフリーになってからはじめてスケジューリングイベントが起こったと
> すると、他のスレッドにロックを横取りされてしまいます。

だいぶわかってきました。Ruby のスレッドは円形に並んでぐるぐる回っ
ているわけですね。

肝要なのは signal 後、条件を他のスレッドに変更されない事では
なく、signal の後は(1周以上したとしても)必ず、しかも早めに
wait のスレッドにロックが戻る事ですね。

巧妙ですね。別世界のプログラム。(うーん、まだ完全には理解
していない。)

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