直井と申します.
rubyを使い始めてまだ1ヶ月弱の新参者です.
現在とあるサーバプログラムをrubyで作ろうと思い,rubyリファレンスマニュアル
の添付ライブラリTCPServerにあるスクリプト(スレッド側)を叩き台にしていた
のですが,mutexのsynchronizeによりロックをかけるとデッドロック状態になって
しまう状です(以降下リスト参照).しかし(1)をコメントアウトし,synchronize
の代わりにlockを使用する(#1を外す)とデッドロックは起こらず下文まで実行し
ます.違う場所にある#2のsynchronizeではデッドロックは起こらないようです.
現状では同一の動作をするとされるsynchronizeとlock-unlockで違う動作をするこ
とから,プログラム文が悪かった場合どこがいけないのか判断できかねています.
よろしければアドバイスをお願いします.
確認用のクライアントは同じページにあったTCPSocketの例を用いました.
rubyのバージョンは1.4.4,実行環境は
Red Hat Linux release 6.1J (Cartman)
Kernel 2.2.12-32 on an i586
ですが,Solarisでも実行しています.
--------------------------------------------------------------------------
require "socket"
require "thread"
$m = Mutex.new
gs = TCPserver.open(1234)
addr = gs.addr
addr.shift
printf("server is on %d\n", addr.join(":"))
while TRUE
ns = gs.accept
print(ns, " is accepted\n")
Thread.start do
$m.synchronize do # (1)ここでデッドロック?
#1 $m.lock # #1を外し(1)コメントアウトするとOK
s = ns
end
#1 $m.unlock
while s.gets
#2 $m.synchronize do # #2を外してもデッドロックは起こらない
s.write($_)
#2 end
end
print(s, " is gone\n")
s.close
end
end