• 締切済み

ファイルロックについて

以下のようなプログラムを作り実験しているのですが、よくわからない事態になっています。 まず、ブラウザを2つ用意して、一方のブラウザで実行した後、すぐに2つめのブラウザで実行します。 mkdirの場合、$which=1として、2つ目を実行すると、busyとでます。これは1つ目がロックしているからということは分かります。 しかし、symlinkの場合、2つ目でもbusyという文字はでず、何事もなかったように両方ともOKと表示されます。これは本当にロックできているのでしょうか。また、この場合、lock.cgiが生成されません。 また、サーバーによってはmkdirで試行すると、まだロックしていないにもかかわらず、busyとでるのもあります。これは、mkdir方式が対応していないと考えればよいのでしょうか。 ------------------------ #! /usr/local/bin/perl $lockfile = "./lock.cgi"; $which = 1; filelock(); sleep 10; fileunlock(); error("OK"); sub error{ print <<END; Content-type: text/html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML><HEAD> </head> <body> $_[0] </body></html> END exit; } sub filelock { if (-e $lockfile) { # 3分以上古いロックは削除する ($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { fileunlock(); } } local($retry) = 2; if($which){ #mkdir関数式ロック while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error("busy"); } sleep(1); } }else{ # symlink関数式ロック if ($lockkey == 1) { while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error("busy"); } sleep(1); } } } } sub fileunlock { if($which){rmdir($lockfile);}else{unlink($lockfile); } }

  • Perl
  • 回答数1
  • ありがとう数0

みんなの回答

  • onosuke
  • ベストアンサー率67% (310/456)
回答No.1

>また、サーバーによってはmkdirで試行すると、 >まだロックしていないにもかかわらず、busyと >でるのもあります。 まず,$!を調べてmkdir失敗の原因を探るべきでしょう。 while (!mkdir($lockfile, 0755)) { &error($!); といった具合に。

関連するQ&A

  • ロックファイルについて

    検証をかけたところロック中になってしまいます。 自分ではわからないので…すいませんが確認をお願いいたします。 #▼ロックファイル sub lock { $symlink_check = (eval { symlink("",""); }, $@ eq ""); if (!$symlink_check) { $c = 0; while(-f "$LOC") { $c++; if ($c >= 3) { &error("■ロック中"); } sleep(2); } open(LOCK,">$LOC"); close(LOCK); } else { local($retry) = 3; while (!symlink(".", $LOC)) { if (--$retry <= 0) { &error("■ロック中"); } sleep(2); } } } sub COPY { $COPY="<div align=right><a href=http://www.jline.co.jp/fn/></a></div>";} sub error { if (-e "$LOC") { unlink($LOC); } print "Content-type: text/html\n\n"; print "<html><head><title>$TITLE</title></head>\n"; print "<body>\n"; print "■エラー<hr>\n"; print "$_[0]\n"; print "</body></html>\n"; exit; }

    • ベストアンサー
    • CGI
  • $retry--の「--」の意味は?

    $retry--の「--」の意味は? ファイルロックについて調べていたら function lock(){ //ロックファイル $file = "lock.txt"; $lockDir= "lock/"; $lockfile = $lockDir . $file; //再挑戦回数 $retry = 3; //30秒以上古いロックは削除する if (file_exists($lockfile)) { $mtime = filemtime($lockfile); if ($mtime < time() - 30) { unlock($file); } } //ロック用ディレクトリを作成する while (!@mkdir($lockfile, 0755)) { if ($retry-- <= 0) { print "只今混雑しています。";exit;} sleep(1); } } のコードを見つけました。「$retry--」の2回ハイフンでどんな意味なのでしょうか? ちなみに他に書き換えるとしたらどんなコードでかけるのでしょうか?

    • ベストアンサー
    • PHP
  • PHPのファイルロックについて

    関数flock();について調べてたのですが、 結局、イマイチ使い所がわかりませんでした。 とりあえずCGIを手本として以下のロックを作ってみたのですが、 もし、flockを使うとしたらどのように使うのかアドバイスして欲しいと思っています。 ↓参考プログラム(echo部は進行を表示するためのもの) <?php define ("LOCK_FILE","./lock/lock.txt"); Lock(); Unlock(); //ロック function Lock(){ if(file_exists(LOCK_FILE)){ if(date(U) - filemtime(LOCK_FILE) > 30){ unlink(LOCK_FILE); echo("古いロック削除<br>"); } } $retry = 5; while(file_exists(LOCK_FILE)){ if($retry <= 0){ echo ("error<br>"); exit; } $retry--; sleep(1); } $lockfile = fopen(LOCK_FILE,"w"); fclose($lockfile); echo("ロック完了<br>"); } //アンロック function UnLock(){ unlink(LOCK_FILE); echo("ロック解除<br>"); } ?>

    • 締切済み
    • PHP
  • ロックファイルの自動削除

    現在、以下のように記述されており、 ロックされてから2秒後に解除されるはずが 2秒後の最初の投稿の際にはロックファイルが存在している旨のメッセージが表示され、 (その際にロックファイルが自動削除されるが投稿はできない) その次の投稿から投稿が可能になるのですが、 2秒後の投稿の際にそのロックファイルを自動削除し、 投稿もできるようにするにはどのように書きかえたらいいのかお教えいただけませんか? ## --- ファイルロック sub lock { if ($_[0]) { $lock_file = $_[0]; } else { $lock_file = $lockfile; } if ($lock_file ne "") { local($flag) = 0; foreach (1 .. 5) { if (-e $lock_file) { sleep(1); } else { open(LOCK,">$lock_file"); close(LOCK); $flag = 1; last; } } if ($flag == 0) { $past_lock = -M "$lock_file"; if ($past_lock * 24 * 60 * 60> 2) { &unlock("$lock_file"); } &error("システムエラー","アクセスが集中しているため、タイムアウトとなりました。(ロックファイルが存在しています)"); } } } ## --- ファイルロック解除 sub unlock { if ($_[0]) { $lock_file = $_[0]; } else { $lock_file = $lockfile; } if (-e $lock_file) { unlink($lock_file); } }

    • ベストアンサー
    • CGI
  • ローカルでは動くのに・・・ロック取得に失敗?

    初心者でただいま、勉強中です。 よろしくお願い致します。 CGIを設定しました。 ローカル(AN HTTPDで確認して動きました)で#!C:/perl/bin/perlと書いたところを、アップするとき、レンタルサーバーの指定に書き換えアップしたのですが・・・何故か掲示板なのに、 「ただいま混み合っています。」とロックを取得する(失敗した場合は処理を終了する)場面で止まっているようです。 この場合、レンタルサーバーがロックを受付ないのでしょうか? sub lock { ( $lockdir_name ) = @_; $retry_cnt = 5; # リトライカウント $sleep_sec = 1; # 待ち時間(秒) $yuukou_sec = 60; # 有効時間(秒) $lock_flg = 0; # ロックフラグ(1:ロック済 0:ロック不可) foreach( 1..$retry_cnt ) { if( mkdir( $lockdir_name, 0755 ) ) { $lock_flg = 1; last; } else { sleep( $sleep_sec ); } } if( !$lock_flg ) { @stat_data = stat $lockdir_name; if( ( time - $stat_data[9] ) > $yuukou_sec ) { rmdir $lockdir_name; } } return $lock_flg; } #***** アンロックを行う sub unlock { ( $lockdir_name ) = @_; rmdir $lockdir_name; } 他に考えられる簡単な失敗など、考えられることがありましたら、是非何でも、お願い致します。

    • ベストアンサー
    • Perl
  • symlinkがうまくいってない?

    サーバーをcentos5からcentos6に変更しました それまでは動いていたCGIの一部が使えなくなりました symlinkを使用するCGIを使用した時に 途中で終わるようなのです どうもsymlinkにかかわるところでエラーがでるみたいです 簡単なCGIを作って実行しましたところ test.cgi ============================ #!/usr/local/bin/perl print "Content-type: text/html\n\n"; print "<html>\n"; print "<head>\n"; print "<meta http-equiv=\"Content-Type\" content=\"text/html;\">\n"; print "<title>test</title>\n"; print "</head>\n"; print "<body>\n"; print "テスト開始</br>\n"; $lockfile= "./test.lock"; $retry = 5; while (!symlink(".", $lockfile)) { if (--$retry <= 0) { &error("BUSY"); } sleep(1); print "リトライ$retry回目</br>\n"; } unlink($lockfile); print "テスト終了</br>\n"; print "</body>\n"; print "</html>\n"; exit; ============================ 結果 <html> <head> <meta http-equiv="Content-Type" content="text/html;"> <title>test</title> </head> <body> テスト開始</br> リトライ4回目</br> リトライ3回目</br> リトライ2回目</br> リトライ1回目</br> と途中で止まっています 希望の結果は テスト開始 テスト終了 の文字がHTMLに表示されたいのですが どこを確認すればよいのかわかりません Perl文法チェッカーにて Perlのパスや実行権ありやsyntax OKは確認していますが このエラーへの対処がわかりません httpdのエラーログでは [日付] [error] [client xxx.xxx.xxx.xxx] Undefined subroutine &main::error called at /home/web/public_html/cgi/test.cgi line 13. と出ていますのでperlがおかしいとは思うのですが。。。 確認すべき場所がわかりません 確認すべきことを教えてください お願いします バージョン Server version: Apache/2.2.15 (Unix) Server built: Aug 13 2013 17:27:11 perlのバージョン This is perl, v5.10.1 (*) built for i386-linux-thread-multi

  • 極めて初歩的な質問ですみません

    PERLの勉強をつい最近はじめました。 参考にしている本のどこを探してもみつからなかったので、質問させていただきます。 sub lock{ $c = 0; while (-f $lockfile) { $c++; if( $c >= 5 ){ print 'BUSY 少し時間を置いてもう一度登録してください。',"\n"; exit; } sleep(1); } open(LOCK,">$lockfile"); close(LOCK); というサブルーチンがありまして、分からないのはwhile構文の条件の記述です。 (-f $lockfile) とは、-fとは、どういう意味なのでしょうか。 if(! -f $mail01 ){ open(OUT,">$mail01"); close(OUT); というところにもありました。 どうぞ教えてやってください。超初心者なので、どうぞよろしくお願いします。

    • ベストアンサー
    • Perl
  • ロックファイルの確実性について

    たとえばカウンタなどを作ろうと思ったとき、データを保存する ファイルを2重にアクセスできないようにするために、ロックファ イルを用意するのが一般的だと思います。 しかし、単にロックファイルを作って、それを if (-e $lockfile) {~~} などとやっても、けっこう頻繁に2重アクセスされてしまいます。 実際、以前、1000アクセス/日あるページを運営していたとき、上の 方法では3日に1回は壊れました。 上の方法は、理論上はありえないはずなのに、なぜおこるのでしょうか? また、ロックファイルではなくロックディレクトリを作って、 unless (mkdir ("./lock", 0777)) {~~} と行うことによっても、同様の判定が可能かと思いますが、 こちらの方法でもやはり2重アクセスが発生してしまうことが あるのでしょうか? その確立は、ロックファイルと同一レベル でしょうか? また、発生するならば、ディレクトリシステム上に 同じ名前のディレクトリが2つ存在することになるのでしょうか? もしわかる方がいらっしゃいましたら、ぜひ教えてください。

    • ベストアンサー
    • CGI
  • BBSについて

    初心者です。BBSを作ろうと思って、kent-webさんのサイトから画像Up可の掲示板のスクリプトをDLしました。http://www.kent-web.com/bbs/joyful.html しかし以下の点がわかりません。 ・ # ロックファイル名   $lockfile = './lock/joyful.lock'; と書いてあるので、lock/joyful.lockというディレクトリをつくったのですが、書き込んでみると、 LOCK is BUSYとでます。ファイルロック形式がよくわからないときは2にしろとかいてあったので2にしてます。    # ファイルロック形式    # → 0=no 1=symlink関数 2=mkdir関数    $lockkey = 2; あと画像をUpする場所はどうやって確保したらよいのでしょうか? どうかご教授おねがいします。m(_ _)m

    • ベストアンサー
    • Perl
  • ロックしたディレクトリが消えない(?)

    flock関数を使い、 $lockfile="./lock/lock.loc"; sub lock { foreach $i (1..6) { . . . if(open(LOCK,">$lockfile")){ if (flock(LOCK,6)) { $lock_flag = 1; last ; } } . . . } } という風にし、メインルーチンで&lockを実行し、ファイルロックしたのですが、flock(LOCK, 8)を使い忘れ、あとでFFFTPを使ってこれを消そうとしても、なにやらディレクトリが永遠に続いている感じになってしまい消せません。 /lock/lock.loc/lock.loc/lock.loc/lock.loc/lock.loc/... という風になっています。 それと元からlock/lock.locというディレクトリが存在したままflockを使ってしまったかどうかはちょっと確認していなかったのですが、使う前にあったとしたらlock.locはファイルではなく、ディレクトリです。 (mrdirを使ったロックなどをいろいろ試していたためです。) うまく説明できなかったのですが、どうすればこれは消せますか?後でflock(LOCK, 8)をやっても直りません・・ アップしたサーバーは@niftyです

    • ベストアンサー
    • Perl