• 締切済み

排他処理

こんにちは。 定期的にperlスクリプトを動かしてファイルを作成し、http(Apache)でそのファイルを参照するシステムを作成中です。 このとき、作成中の中途半端なファイルを読まないようにしたいのですが、 どのようにするのがよいでしょうか? CGIスクリプトで掲示板等のファイルにアクセスする際の排他制御についてなら、いろいろと情報もあるのですが、今回のようなケースについてはどうも情報が見つかりませんでした。 単純にテンポラリファイルを作って最後にrenameするだけでもよさそうなのですが、どの程度確実なものでしょうか。 あるいはapacheの設定でなにかうまい方法があるのでしょうか? どなたかご存知でしたら、ご教示願います。 OSはSolarisです。よろしくお願いします。

みんなの回答

回答No.3

> perlスクリプトでファイル(.html等)を自動生成するのですが、そのファイルが非同期にapache側からアクセスされるのです。 ファイルロックが無理なら、 それでは、あらかじめランダムなファイル名でテンポラリファイルとして作成しておいて、ファイルが完成したらrenameで公開ディレクトリに移動するとか、 他の方法は採れないのでしょうか? ある意味renameによるファイルロックと同じ方法ですが。 Apacheのアクセスではなく、他人がアクセスしてくるだけなら、 たとえばメニューファイルを最後に作り直してギリギリまでリンクしないようにするなど、ファイルを作る順番で対応できるかもしれません。 補足 > ANo.3 > Solarisなら大丈夫と思いますが、OSがファイルをロックする機能を持っていなければflockの後でもopenされます。 「大丈夫」 Solarisもファイルをロックする機能を持っているだろうから、flockできたら他のアプリケーションからアクセスされることはないだろう、という意味です。 openとflockの間ならアクセス可能です。

titokani
質問者

補足

お返事ありがとうございます。 >ファイルロックが無理なら、 そのファイルロックなのですが、いろいろと検索してみると、 ・協調ロック ・強制ロック とがあって、unixで一般的なのは協調ロックであるとの記述が多いのです。 協調ロックの場合、そのファイルをオープンするすべてのプロセスがロックのためのコードを書かねばならないらしく、そうすると、apache側でロックに対応していない場合、ロックしても無意味なのかなと思われるのです。 この点、実際のところはどうなのでしょうか? >それでは、あらかじめランダムなファイル名でテンポラリファイルとして作成しておいて、ファイルが完成したらrenameで公開ディレクトリに移動するとか、 >他の方法は採れないのでしょうか? renameなのですが、apache側でファイルを読み込んでいる最中にrenameされた場合にはどうなるのでしょう? ファイルの途中から新しい内容を読み込んでしまったりはしないのでしょうか? 細かい話で申し訳ありませんが、よろしくお願いします。

回答No.2

本来アクセスするはずのないApacheがアクセスすると言うことは、システムファイルをいじってますか? まぁ、システムファイルかどうかはあまり関係ないのですが、排他処理ならファイルロックで解決すると思います。 ファイルロックはOSに依存するところが大きいですが、flockはお勧めしません。 use Fcntl; open($FP, '+>', $file); flock $FP, LOCK_EX; openとflockの間に1行あいていますから、この間に他のプログラムがこのファイルに介入すると、openされてしまいます。 Solarisなら大丈夫と思いますが、OSがファイルをロックする機能を持っていなければflockの後でもopenされます。 use Fcntl; sysopen($FP, $file, O_RDWR|O_EXLOCK) OS依存ですが、もしファイルロックが成功するなら、これで十分だと思います。 これでダメならrenameを使ったファイルロックですね。 mkdirによるロックではオリジナルのファイルはそのまま残りますから、やはりopenされてしまいます。 renameしてしまえば、ファイルは存在しなくなりますから、他のアプリケーションは読み込みモードでのopenができなくなります。 ただしファイルの作成はできますから、その問題は残ります。 弊害が多いですが、上位ディレクトリのディレクトリ名をrenameするとかは出来るかも知れません。 ディレクトリがなければディレクトリを作ってファイルを作成、とかやられたらお手上げ。

titokani
質問者

補足

>本来アクセスするはずのないApacheがアクセスすると言うことは、システムファイルをいじってますか? 違います。 >定期的にperlスクリプトを動かしてファイルを作成し、http(Apache)でそのファイルを参照するシステムを作成中です。 perlスクリプトでファイル(.html等)を自動生成するのですが、そのファイルが非同期にapache側からアクセスされるのです。 なので、apache側でなんらかの設定を行わないと無理なのかなとも思うのですが、どうなのでしょうか?

回答No.1

> このとき、作成中の中途半端なファイルを読まないようにしたいのですが、 > どのようにするのがよいでしょうか? よくわかりませんが、 作成中のファイルをロックすれば、他から読まれなくなりますし、 自分で作ったファイルを自分で読まないようにするなら、ファイル名をグローバル変数に持っておいて、そのファイルを二重にopenしなければいいんじゃないでしょうか。 (ていうかロックしておけばopenできないと思いますが) ファイルハンドラを持っているのに、さらにopenする必要はないと思いますけどね。

titokani
質問者

補足

>自分で作ったファイルを自分で読まないようにするなら、ファイル名をグローバル変数に持っておいて、そのファイルを二重にopenしなければいいんじゃないでしょうか。 すみません、ちょっと表現が曖昧でした。 apacheから読まれないようにということです。 あと、apacheがアクセス中に書き換えを行わないようにすることも必要でした。 >作成中のファイルをロックすれば、他から読まれなくなりますし、 具体的にどのようにすればよいのでしょうか? 調べると、flockなどがあるようですが、apacheとの同時アクセスの際にも有効なのかどうかよくわからないのです。

関連するQ&A