N.Katoh
typer_jp****@yahoo*****
2006年 2月 10日 (金) 02:08:04 JST
加藤です。 ちょっと細かい所を... というつもりでしたが、書いている途中で細かくない事を発見しました。 ファイルの内容が消えてしまう原因ですが、確かに書き込みが競合すると「一部 分」が消えてファイル内容が壊れてしまう可能性があります。ただ、すべて消え てしまう可能性の高いのは、「読み込みと書き込み」が競合する場合です。実際 の動作で言うと、 1. プロセスA:open(CONFIG,">$fullpath")→ファイルクリア 2. プロセスB:open(CONFIG,$fullpath)→空のファイルを読んでしまう 3. プロセスA:print CONFIG $text;→ファイル出力(実際にはclose(CONFIG)時) 4. プロセスB:空のデータを元に一行だけのデータを保存 と言うわけで、一番簡単な方法は読み込み時にもロックを掛けるというものです が、このロックは排他ロックのみですので、使用頻度が高いload_config_textに それをやってしまうとパフォーマンス低下が無視できなくなる気がします。 flockの共有ロックを使えばその点はクリアできると思いますが、flockを使わず 実装するとなるとそこそこ面倒ですし、さらに次に上げる問題もありますので、 次の解決策にした方が良いと思います。 上記を解決しても残る問題があって、読み込みから更新・書き込み「までの間」 に競合する場合で、それぞれがファイルを読み、それぞれ更新すると、先に更新 した変更が反映されないと言う事がおきます。しかし、読み込みから書き込み完 了までずっとロックするのは効率悪過ぎます。 そこで、「一部のみ更新する」という関数を新規に作って、それを使うようにし た方が良いと思います。 以下、途中まで書いた文をついでに。 On Thu, 09 Feb 2006 23:27:35 +0900 あき <attin****@kk*****> wrote: > あきです。 > > BBS-雑談掲示板/161やBBS-サポート掲示板/451に関する対処についてですが、 > ファイルをロックしているロジック、確認させていただきました。 > じっくりと追ってみたのですが、ロックの手順等では、私には問題は見つけら > れませんでした。(私は今までflock()でしか対応したことが無いので、ディ > レクトリをロックファイルの代わりとして使う手法については、自信がありま > せん) レアケースですが、穴がなくはないです。 ロックしっぱなしになった場合の回避部分 > my $mtime = (stat($lock))[9]; > rmdir($lock) if($mtime < time() - 60); で、 0. 60秒以上ロック状態 1. プロセスAがstat→この時点ではまだ長期ロック状態変わらず 2. プロセスBがstat→同じく長期ロック状態変わらず 3. プロセスBがrmdirからmkdirまで実行→プロセスBがロック成功→処理続行 4. プロセスAがrmdir→プロセスBのロック破壊 となります。が、これが起こるのには「60秒以上ロック状態」というのが不可欠 で、それはレアケースですし、その時点ですでに異常状態ですし、さらに実際に 内容が消えるためには、その上で書き込みが競合する必要がありますから、そう 起こるものではく無視できる範囲だと思います。 と書いていて気がついたのですが、せっかくなのでその部分も残します:-) -- typer <typer_jp****@yahoo*****> like perl, stay FreeBSD http://freebsd.g.hatena.ne.jp/TransFreeBSD/ use fswiki http://aaa-www.net/~typer/cgi-bin/wiki.cgi/diary and named Noboru Katoh <typer****@chive*****>