Naoki Takezoe
takez****@gmail*****
2006年 2月 10日 (金) 10:10:09 JST
竹添です。 06/02/10 に N.Katoh<typer_jp****@yahoo*****> さんは書きました: > 加藤です。 > ちょっと細かい所を... > というつもりでしたが、書いている途中で細かくない事を発見しました。 > > > ファイルの内容が消えてしまう原因ですが、確かに書き込みが競合すると「一部 > 分」が消えてファイル内容が壊れてしまう可能性があります。ただ、すべて消え > てしまう可能性の高いのは、「読み込みと書き込み」が競合する場合です。実際 > の動作で言うと、 > > 1. プロセスA:open(CONFIG,">$fullpath")→ファイルクリア > 2. プロセスB:open(CONFIG,$fullpath)→空のファイルを読んでしまう > 3. プロセスA:print CONFIG $text;→ファイル出力(実際にはclose(CONFIG)時) > 4. プロセスB:空のデータを元に一行だけのデータを保存 あ、そうですね、確かに。 > と言うわけで、一番簡単な方法は読み込み時にもロックを掛けるというものです > が、このロックは排他ロックのみですので、使用頻度が高いload_config_textに > それをやってしまうとパフォーマンス低下が無視できなくなる気がします。 あと、厳密にやるのであれば、読み込みと書き込みに対して別々にロックを かけるのではなく、読み込み→書き込みという一連の操作に対してロックを かけないとダメですね。 > flockの共有ロックを使えばその点はクリアできると思いますが、flockを使わず > 実装するとなるとそこそこ面倒ですし、さらに次に上げる問題もありますので、 > 次の解決策にした方が良いと思います。 > > 上記を解決しても残る問題があって、読み込みから更新・書き込み「までの間」 > に競合する場合で、それぞれがファイルを読み、それぞれ更新すると、先に更新 > した変更が反映されないと言う事がおきます。しかし、読み込みから書き込み完 > 了までずっとロックするのは効率悪過ぎます。 > > そこで、「一部のみ更新する」という関数を新規に作って、それを使うようにし > た方が良いと思います。 Util.pmに追加することになると思いますが、どんなインターフェースがいい んでしょうねぇ。値の読み込み→書き込みに対してロックをかけるとなると、 すぐに思いつくのは現在の値のハッシュを受け取って、更新済みのハッシュ を返すような関数のリファレンスを渡す方法とかですが…。 とりあえず上書きされちゃってもファイルが破壊されなければいいということ であれば加藤さんの仰るように一部のみ更新する関数でもよさそうですが、 どうせやるなら、やはり正しい値を保障できる方法がいいですよね。 -- Naoki Takezoe <takez****@gmail*****>