原です。
次の様な、どう考えても無限ループになりそうなスクリプトが、
実は適当な時間で fail します。
-----^ test_thread_hash.rb
#!/usr/local/bin/ruby
@bar = {}
$s = "a"
def foo(n)
loop do
s0 = $s
if (@bar[s0] = TRUE) && !@bar[s0]
fail "#{n})" + s0
end
$s = $s.succ
end
end
Thread.start { foo(0) }
Thread.start { foo(1) }
sleep
-----$ test_thread_hash.rb
これで3日ハマってしまった。^^; やっぱり Hash は保護した方が
いいみたいですね。
thread.rb を初めて見てみたんですが、Thread.exclusive という隠
しメソ?と run と stop だけを使ってうまいこと作ってあるんです
ねえ。感心してしまった。
で、気づいたんですが、push, pop の保護はここではほとんどされて
ません。
それから、ちょっとルーズな所があって、例えば class Queue の
def pop non_block=FALSE
if @que.length == 0
raise ThreadError, "queue empty" if non_block
@waiting.push Thread.current
Thread.stop
end
@que.shift
end
で、 / que.length と @que.shift の間のタイムラグがやばい気がし
ます。
もうひとつ。Queue では、pop が実は shift で実装されているとい
うのが、、。 Queue を継承して shift, unshift, delete,.. など
というメソッドを増やして QueArray みたいなクラスを作ろうとす
ると、ややこしくなります。Queue#in, out みたいな名前の方が良
かったかも。
もちろん Queue のイメージからいうとこの pop はもっともではあ
るし、QueArray は独立に作るのがスジかもしれないですが。
---===-=-=-=-=-=-=-=-=======--=-=-=-==-=-===-=-=-=-=-=-=--=-==-=--
Shin-ichro Hara(Nagaoka Univ.of Tech.)