[Fswiki-dev] Re: ファイルロックに関する処理

Back to archive index

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*****>



Fswiki-dev メーリングリストの案内
Back to archive index