In message <200006142243.HAA20586 / hanare00.math.sci.hokudai.ac.jp> gotoken / math.sci.hokudai.ac.jp writes: > > Thread.start do > > $m.synchronize do # (1)ここでデッドロック? > >#1 $m.lock # #1を外し(1)コメントアウトするとOK > > s = ns > > end (略) > ので,ブロック内で Mutex#lock を呼ぶと当然deadlockになります. # そりゃそうですけど. いや,そうじゃなくて, $m.synchronize do s = ns end だとデッドロックした様子で, $m.lock s = ns $m.unlock だと動くようだ,っていう話だと思いますよ. 理由は「あるブロックで導入されたローカル変数はそのブロック内でのみ有効 になる」からです.子スレッドの方は何もいわずに例外で終了してしまってる んです. # Thread.abort_on_exception = true って頭の方に加えて実行してみると, # "undefined local variable `s'" っていってちゃんと全体が落ちます :-) # つい最近おんなじようなことしてはまってたのは秘密 :-) つまり Mutex#synchronize のブロックの外では s が定義されてないんです. lock/unlock を使った場合にはブロックを導入してないので大丈夫. synchronize を使いたいならその前に `s = nil' とかいれといたら良いでしょ う. ちなみにこの例の場合,上記のブロック内で新たに導入されたローカル変数は ブロックローカル,というルールにより,s はスレッドローカルになります. だからそもそもここで相互排除を行う必要は無かったりして. # ....ですよね? 親スレッドが accept したせいで ns のアクセスが競合するっ # ていう事は無かったですよね? さらに下の gets して write,っていう動作の方でも,s にアクセスできるの は s をもってるスレッドだけなので,やっぱり相互排除はいりません. -- 柳川和久 @ 東大阪市 . 大阪府 June 15, 2000 「田園の,日差しの農場?」「ふざけるにゃ!」