- ベストアンサー
CGI二重起動防止ロック処理
ズバリ、CGI二重起動防止ロック処理のソースをもしよかったら、だれか教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
実用的には、Sephy さんの方法でほぼ十分だと思います。しかし、 もし絶対に二重に起動しては困るという場合には、二つのCGIがほ ぼ同時に起動されてしまうと、つまり相次いで getc して中身がな いことを確認してしまうと、二つともロックが成功してしまうので 完全ではありません。 UNIX 上の Perl であると仮定しますが、ロックに使える機構とし ては、flock か fcntl を使う方法、link, symlink, mkdir は存在 していると成功しないことを利用する方法、umask を適当に(0777 あたりに)セットしてアクセス禁止のファイルを作る方法が考えら れます。 flock/fcntl は UNIX がプロセスの存否を管理しますので、プロセ スが不意に死んでもロックがかかりっぱなしにならないという利点 があります。このうち、fcntl は UNIX の低レベルのインタフェー スなのでちょっと面倒かもしれません。flock が簡単でしょう。 まともな perl の参考書なら、flock の解説もあると思います。 man perlfunc で flock の項を調べてもサンプルのコードが載って います。 もしコードが必要なら、補足してください。ただし、ロックに失敗 した側がは、そのまま終了してしまえばいいのか、ロックできるよ うになるまで待ってロックするのかで変わりますので、明記してく ださい。また、ロック後に操作するファイルがあらかじめ固定され ている場合は、そのファイルを使ってロックする方が、無駄なファ イルを作らずにすみます。
その他の回答 (5)
- Sephy
- ベストアンサー率35% (7/20)
アクセスログを取るCGIを使っているんですか? だとすれば多重起動を防止しなければならない状況とは おそらくカウントを取る時でしょう。 ただ下記の私のソースだと多重起動時に終了させてしまうので、 die"busy" を select(undef,undef,undef,0.1) とかに書き換えたほうがいいかもしれません。 後者は「0.1秒待つ」という意味です。 どちらにせよ下記の指摘のように、 同時にアクセスがかかった場合には弱いと思います。
- Sephy
- ベストアンサー率35% (7/20)
>OKWebさんは<の変換の仕方を間違っているみたいなので >ソース書いたけど見づらいです。 あ、回答するときの表示だけみたいです・・・ 忘れてください。
- Sephy
- ベストアンサー率35% (7/20)
さっそく自己補足・・・ ---------- # ロックファイル名 $LOCK = 'lock.loc'; # ロックが不正だと判断するまでの時間 $LOCKTIME = 60; # ロック処理 open(LF,"+<$LOCK"); die"busy" if((stat(LF))[9] + $LOCKTIME < time && getc(LF)); print LF 1; close(LF); # ここに処理内容を書いてください。 # アンロック処理 open(LF,">$LOCK"); close(LF); ---------- P.S. OKWebさんは<の変換の仕方を間違っているみたいなので ソース書いたけど見づらいです。 それと、私はロックのためだけにディレクトリのパーミッションを変更するのは気分的に嫌なので、 ファイルの中身で判断するようにしてます。 別にファイルの有無でもいいけど・・・
- Sephy
- ベストアンサー率35% (7/20)
こんな感じでどうでしょう? # ロックファイル名 $LOCK = 'lock.loc'; # ロック処理 open(LF,"+<$LOCK"); die"busy" if(getc(LF)); print LF 1; close(LF); # ここに処理内容を書いてください。 # アンロック処理 open(LF,">$LOCK"); close(LF);
- puchi_pan
- ベストアンサー率50% (3/6)
いくつか種類はあると思いますので参考程度にどうぞ。 必要なら参考ソースをまた書きます。 1, 起動時に何らかのファイル(ロックファイル)を作成しそれが存在すれば、起動しない、プログラムが正しく終了する直前にファイルを消す。 注意としてはプログラムが不正終了したときにファイルが残ってしまうので、それを時間によって消去することが必要。 2,システムのプロセスをみて判断する。 今思いつくのはこのぐらいです。
補足
このソースは、ログを集計するCGI(analyze.cgi)に書けばいいのか、ログを採る&累計カウント表示をするCGI(log.cgi)に書けばいいのかわかりません。後者のほうでやったら、カウンタが表示されなくなりました。 あと、$LOCK = 'lock.loc';のlock.locはこのままでいいのでしょうか。 全くの初心者なので、よく分かりません。もう少し詳しく教えていただけますか。