• ベストアンサー

CGI二重起動防止ロック処理

ズバリ、CGI二重起動防止ロック処理のソースをもしよかったら、だれか教えてください。

  • mri
  • お礼率11% (3/26)
  • CGI
  • 回答数6
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

実用的には、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)
回答No.6

アクセスログを取るCGIを使っているんですか? だとすれば多重起動を防止しなければならない状況とは おそらくカウントを取る時でしょう。 ただ下記の私のソースだと多重起動時に終了させてしまうので、 die"busy" を select(undef,undef,undef,0.1) とかに書き換えたほうがいいかもしれません。 後者は「0.1秒待つ」という意味です。 どちらにせよ下記の指摘のように、 同時にアクセスがかかった場合には弱いと思います。

  • Sephy
  • ベストアンサー率35% (7/20)
回答No.4

>OKWebさんは<の変換の仕方を間違っているみたいなので >ソース書いたけど見づらいです。 あ、回答するときの表示だけみたいです・・・ 忘れてください。

  • Sephy
  • ベストアンサー率35% (7/20)
回答No.3

さっそく自己補足・・・ ---------- # ロックファイル名 $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さんは<の変換の仕方を間違っているみたいなので ソース書いたけど見づらいです。 それと、私はロックのためだけにディレクトリのパーミッションを変更するのは気分的に嫌なので、 ファイルの中身で判断するようにしてます。 別にファイルの有無でもいいけど・・・

mri
質問者

補足

このソースは、ログを集計するCGI(analyze.cgi)に書けばいいのか、ログを採る&累計カウント表示をするCGI(log.cgi)に書けばいいのかわかりません。後者のほうでやったら、カウンタが表示されなくなりました。 あと、$LOCK = 'lock.loc';のlock.locはこのままでいいのでしょうか。 全くの初心者なので、よく分かりません。もう少し詳しく教えていただけますか。

  • Sephy
  • ベストアンサー率35% (7/20)
回答No.2

こんな感じでどうでしょう? # ロックファイル名 $LOCK = 'lock.loc'; # ロック処理 open(LF,"+<$LOCK"); die"busy" if(getc(LF)); print LF 1; close(LF); # ここに処理内容を書いてください。 # アンロック処理 open(LF,">$LOCK"); close(LF);

回答No.1

いくつか種類はあると思いますので参考程度にどうぞ。  必要なら参考ソースをまた書きます。  1, 起動時に何らかのファイル(ロックファイル)を作成しそれが存在すれば、起動しない、プログラムが正しく終了する直前にファイルを消す。 注意としてはプログラムが不正終了したときにファイルが残ってしまうので、それを時間によって消去することが必要。  2,システムのプロセスをみて判断する。  今思いつくのはこのぐらいです。

関連するQ&A

  • 2重起動の防止

    C++Builder5.0でアプリケーションの2重起動の防止 を実現する方法を教えて下さい。

  • プログラムの二重起動防止

    プログラムの二重起動を防止したいんですが、V.B.のようにjavaにも、二重防止の関数があるのでしょうか? あるとすれば、どういったものなのでしょうか?

    • ベストアンサー
    • Java
  • vb.net2003での二重起動防止について

    度々お世話になっています。 vb.net2003でアプリケーションを作りました。 そこで二重起動防止を行いたい為に、Process.GetProcessesByName メソッドを使用して行いました。 二重起動防止は出来ているのですが、ターミナルサービスでリモートデスクトップ接続を行い、同一ユーザーの二重起動防止はしたいですが、1ユーザーでも使用していたら 別ユーザーで起動できません。 何か良い方法はありませんでしょうか? 出来れば解説しているサイトがあれば教えて下さい。

  • 2重起動の防止方法

    Microsoft Visual C++6.0でアプリケーションの2重起動の防止を実現する方法を教えて下さい。

  • 二重投稿防止処理

    PHPの掲示板を作成しています。 現在リロードや連続で送信ボタンを押された際の二重投稿防止処理を作っているのですが、どうしてもうまくいきません。 ログで最新に書かれた記事を呼び出し、送信されたデータと比較し、名前とコメントが一緒であれば二重投稿という扱いにするつもりなのですが、 改行があるとうまくいかないようなのです。 str_replaceを使って<br>タグを削除したり、 \r\nや\rを\nに統一させたり、 両方にtrimを使用してみたりしたのですが、 ソースを見るとフォームで送られてくるコメントのみ、どうしても改行されたままなんです。 これは一体何が原因なのでしょうか? どうしたら改行を含んだデータを比較することができますか?

    • ベストアンサー
    • PHP
  • VB5.0 二重起動防止

    OSWin98/VB5.0を使用しています。同一のシステムの重複起動を防止したいのです。過去ログの、 http://oshiete1.goo.ne.jp/kotaeru.php3?q=644390 を参照し、 http://www.vbvbvb.com/jp/gtips/1101/gCreateToolhelp32SnapshotTh32csSnapprocess.html のサンプルを参考にし、実行中のプロセスに同一のものがあれば、複数起動と判断するようにしました。 しかし、どうしても二重起動されてしまいます。 例1)A.exeを起動、A.vbpをデバッグで実行    →二重起動を検出し、後者は起動されない 例2)A.exeを起動、A.exeを起動    →二重起動が検出されず、後者も起動されてしまう App.PrevInstanceで判断できると思うのですが、例1と同じ方法でもこの場合は、二重起動を防ぐことができません。 他によい方法がある、ここがおかしいんじゃないの?等ありましたら、教えてください。 よろしくお願いします。

  • ロック処理につきまして

    皆様はじめましてナベといいます。よろしくお願いします。 このたび予約状況カレンダー(http://www.dab.hi-ho.ne.jp/appletea/cgikan/yoyaku.shtml)というCGIをダウンロードさせていただき設置しました。 CGIも動き実際に管理画面から予約状況の編集をしたところ、 ロック処理に失敗しましたと表示されました。 動作環境も確認し、マニュアル通りに設置し、そちら以外の動作は問題ないのですが、何をしてもロック処理に失敗したとでてしまいます。 大変素人な質問で申し訳ないのですが、何か解決できる方法をご教授いただけないでしょうか? それでは、よろしくお願いします。

    • ベストアンサー
    • CGI
  • CGIのボタンの処理について

    CGIのフォームにチェックボックスがあってボタンを押すとある処理をさせたいのですが、 <form action="○○.cgi" method="post"> を使って新たなCGIを呼び出さずにフォームのCGIで処理をし、結果を反映させたいのです。もし方法をご存知の方がいましたら教えて欲しいのでよろしくお願いします。 <-------cgiソースの一部----------> print "<input type=\"checkbox\" name=\"re_$n\" value=\"$userdata[$i]\">"; print "<input type=\"button\" value=\"処理\">"; ボタンを押した時に処理をしてすぐさまリロードして同じページに結果を反映させたい!

    • ベストアンサー
    • CGI
  • CGIへ飛ばずに処理だけさせたい

    HTMLのフォームからsubmitしてcgiにアクセスする。 cgiでHTMLからのポストとゲットを読み込んで ログファイルに書き込む。 というCGIを作ったんだけど、 print "Content-type: text/html\n\n"; を書かないと、submitしてからcgiの処理が 止まらないみたいでした。 print "Content-type: text/html\n\n"; を書くと、処理は正常になるけど、cgiファイルに ジャンプしてしまいます。 openで書き込みをする場合、cgiに飛ばずに 処理する方法を教えてください。

    • ベストアンサー
    • CGI
  • CGIの起動が遅い

    Web上から作成したCGIを起動した場合に、そのCGIが存在するサーバ上ではすぐに実行されるのですが、他のPCからサーバにアクセスしてCGIを起動するとブラウザの下部にCGI実行中のメッセージが表示されてから結果が表示されるまでに時間がかかっています。(約30-60秒) 他のネットワーク処理等は普通に実行できるので特にネットワークが重い等の問題はないと思うのですが何が問題なのかアドバイスをお願いします。 サーバOSはRedHat Linux 5.1、apacheはver2.2です。

    • 締切済み
    • CGI

専門家に質問してみよう