From: Keisuke Minami Date: 2001-02-25T01:28:14+09:00 Subject: [ruby-list:28243] Re: CGI でのロック (was: File.rename の例外) こんばんは。三並です。 >> Dir::mkdir はどうですか? > > [ruby-list:13141]という感じですよね? >> また、タイムアウトと排他制御は分けた方がわかりやすいような気がします。 >と書かれていますが、どういうことでしょうか? > ロックディレクトリが異常で残った場合の処理も書かなければいけませんよ ね。 > ># 実は今書いてるロックのプログラムは他人が書いたPerlプログラムの ># 翻訳なんですね。僕自身はロックのアルゴリズムに詳しくないので、 ># 同じアルゴリズムがそのまま適用できれば深く考えずに実現できるので ># 僕としては楽なわけです。(^^; Windowsでの挙動はよく分からないけど ># Linuxだとちゃんと動きそうなので問題なければrenameでいくつもりです。 私の方ではこんな風にやっていますよ。 #あのページを参考にして イテレータを使って、ブロックの中に入れるので ロック解除の処理を書かずにすむのが楽ですね。 ロックをかけるのはこんな感じ。 locking do # 処理 end ---- def locking num = 10 # ロックをかけようとするリトライ回数 timeout = 600 # ロックを異常とみなすまでの時間(秒) lockdir = "lock" lockflag = nil # ロックがかかっているかをチェックするフラグ変数 (0 .. num - 1).each do |i| begin currenttimedir = lockdir + Time.now.to_i # ロックのディレクトリ名に epochからの経過時間を足す File.rename(lockdir, currenttimedir) # ロックをかける lockflag = true break rescue Dir.glob("#{lockdir}*").each do |file| if /^#{lockdir}(\d+)/ # ロックファイルかどうかをチェック if Time.now.to_i - $1 > timeout # タイムアウトを過ぎていたら File.rename(file, currenttimedir) # 古いロックを新しいロック に移行する lockflag = true break end end end end sleep(1) end raise Lock::LockError, "LockError: #{lockdir} #{$!}" unless lockflag # ロックをかけていなかったら例外を発生 begin yield # ブロックの中を実行する ensure File.rename(currenttimedir, file) if lockflag # ロックをかけていたら ロックの解除 end end  ___________________________ 〆 |  三並 慶佐 (Keisuke Minami) |  E-mail:keisuke@rccn.com |  「do yourself better」 |  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄