• ベストアンサー

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

ファイルのロック方法を下記の様にしてロックさせていますが、同時ににアクセスが合ったときにどちらかが$add_text;を書きこまれないので順次書き込まれる様にしたいのですが、何方かご教授してもらえませんか? #!/usr/bin/perl use Fcntl ':flock'; open(ADD_DB,">>$log"); flock(ADD_DB, LOCK_EX); print ADD_DB "$add_text;\n"; flock(ADD_DB, LOCK_NB); close(ADD_DB);

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

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

  • ベストアンサー
  • Ethersky
  • ベストアンサー率71% (168/235)
回答No.1

flockでのロックは、元から他のプロセスが既に同じモードでロックしている場合、ロックが解除されるまで待つようになっています。 但し、ファイルハンドルは同じでないといけません。

meikenpochi
質問者

お礼

Etherskyさん、回答ありがとうございます。 >ロックが解除されるまで待つようになっています。 知りませんでした。flockって便利ですね。

関連するQ&A

  • flockの挙動がおかしい。。。

    おそれいります。 親プロセスから子プロセスを複数呼び 子プロセスが全て終わった後に次の手順に移行する。。。という処理をflockを使って作っているのですが、 うまくいきません。 下の「main.pl」を実行すると、「lock.pl」を10回呼び出して、 すべて終了したら「OK」と表示したいです。 lockというファイルを全部のプロセスで共有して、 子の全部の処理が終わった時点で、mailにロックが移る。。。という動きを想定したのですが、 なぜか、数回実行しているとMAIN LOCK(1) が最後に発動しているにもかかわらず、 子プロセスが終了していないのに「OK」の表示を出してしまいます。 flockは順番を守らないのでしょうか・・・・????? どのようにしたらうまく動くでしょうか。。。。 ==> main.pl <== #!/usr/bin/perl use Fcntl ':flock'; for (1..10){ system("./lock.pl $_ &"); } sleep 5; # 子プロセスが開始するまで待つ print qq("MAIN LOCK\n"); # ... (1) open LC,"+<lock" or die; flock LC,LOCK_EX; sleep 1; print qq("OK\n"); ==> lock.pl <== #!/usr/bin/perl use Fcntl ':flock'; print qq(lock $ARGV[0]\n!); # ... (2) open LC,"+<lock" or die; flock LC,LOCK_EX; sleep $ARGV[0]; print qq(release $ARGV[0]!\n);

    • ベストアンサー
    • Perl
  • ファイルの最後の行から表示させる(最新情報を5回分だけ表示)

    ファイルの最後に1行追加し、6行以上になるとファイルの先頭を1行削除。 表示は最後の行から行うスクリプトを作りたいのです。 新しい情報を5回分だけ表示する様にしたかったのですが、余りにも力技なのでもう少しスマートにやる方法を教えてもらえませんか? ----sort.txt---- 1a 2b 3c 4d ---------------- #!/usr/bin/perl $fname = "sort.txt"; print "Content-type: text/html;\n\n"; $aaa="5e"; open(OUT, ">>$fname"); flock(OUT, LOCK_EX); print OUT "$aaa\n"; flock(OUT, LOCK_NB); close(OUT); open(IN, "$fname"); $cnt = "0"; while($line = <IN>){ $a[$cnt] = "$line"; $cnt++; } close(IN); if($cnt > 5){ open(OUT, ">$fname"); flock(OUT, LOCK_EX); $cnt = "0"; while($cnt < 6){ if($cnt > 0){ print OUT "$a[$cnt]"; } $cnt++; } flock(OUT, LOCK_NB); close(OUT); } $cnt = "0"; open(OUT, "$fname"); @buff = <OUT>; close(OUT); foreach $line ( reverse @buff ){ $cnt++; print "$line<br>\n"; } exit();

    • ベストアンサー
    • Perl
  • 【ruby】flockで掛けたロックを参照したい

    複数プロセス間で、一つのファイルに対して読み書きしたいです。 その際、ファイルへの書き込み中は、ファイルの読み込みを抑止したいです。 また、読み込みの処理はファイルのロックを参照するだけで、ファイルへのロックは掛けない様にしたいです。 そこで、以下二つプログラムを作成して、簡単な検証を行いました。 ■プログラム1 キーボードからの入力があるまで、ファイルをロックする。 #!/usr/local/bin/ruby file='./hoge.txt' f=open(file,'r+') ret=f.flock(File::LOCK_EX|File::LOCK_NB) STDOUT.write 'Hit any key' STDIN.gets.chomp ■プログラム2 ファイルがロックされているか状態を取得する。 #!/usr/local/bin/ruby require "fcntl" file='./hoge.txt' f=open(file,'r') arg="" f.fcntl(Fcntl::F_GETLK,arg) l_start,l_len,l_pid,l_type,l_whence = arg.unpack('VVVSS') puts l_len ※プログラム2は、fcntlの使い方がマニュアルを読んでもよく理解できなかったので、 手探りで記述しました。 実行すると、プログラム1はエラー無く動きましたが、プログラム2は以下の様なエラーが 出てしまいます。 fcntl.rb:6:in `fcntl': Invalid argument - ./hoge.txt (Errno::EINVAL) from fcntl.rb:6 環境は、unixレンタルサーバ(FreeBSD)です。 上記方法では、上手くいきませんでした。 flockでファイルにロックが掛っているか否かを、そのファイルにロックを掛けることなく 調べるにはどうしたら良いのでしょうか? ご指導のほど、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • 新しいログの書き込み

    新しいログを追加で上に書き込む方法はどのようにしたらよいのかアイディアがありません。 ご教授願います。 if($mode eq "html"){ flock(FH, LOCK_EX); open(FH,"${datafile}"); @html = <FH>; close(FH); flock(FH, LOCK_NB); $html = join('',@html); @html = split(/$chtml/ , $html); $html[1] = $data; $html = join($chtml,@html); flock(FH, LOCK_EX); open(FH,">$datafile"); print FH $html; close(FH); flock(FH, LOCK_NB);

  • ロックしたディレクトリが消えない(?)

    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
  • flockについて

    http://www.freespace.jp/phpstudy.php4 のサイト様を拝見したり、フリーで配布されているスクリプトを見ると、書き込むファイルに対して、 $fp = fopen('bbs.log', 'r+'); flock($fp, LOCK_EX); … とやっていると思うのですが、perl記述のcgiで掲示板を作成したときは、書き込むファイルとは別にロック用のファイルを用意し、(perl記述です) open(LOCK,"+<$lockfile"); flock(LOCK,2); open(IN,"$logfile"); .... close(IN,"$logfile"); open(OUT,"$logfile"); .... close(OUT,">$logfile"); としていました。(書き込むファイルが2つあったのでこのような方法をとってました) そこでphpでも同じ方法は使えるのでしょうか? $fp = fopen('bbs.log', 'r+'); flock($fp, LOCK_EX); … の方法を使おうと思っていたのですが、最初にログファイルを読み込むとき、 file("bbs.log"); という風にしているので、flockに記述すべきファイルハンドルが見当たりません。仮に取得できたとしても、file();の仕様からして内部にcloseが入ってそうなので、flockできたとしてもcloseで無効になってしまわないかが心配です。なのでこの場合はやはり別にログファイルを用意しないとできないということでしょうか。

    • ベストアンサー
    • PHP
  • ファイルの読み書きについて教えてください。

    フォームから投稿されてきた内容を、テキストファイルに書き込むphpを作っているのですが、 flock関数で、誰かが書き込んでいるときに他の人が書き込めないようにファイルをロックしたいと思っています。 以下のソースでLOCK_EXとLOCK_UNは正しく動作するでしょうか。 いまいち不安で困っています。 //ポストされてきた内容が$nameに入ります $name = $_POST['name']; $fh=fopen("test.txt","a+"); flock($fh, LOCK_EX); fwrite($fh,"$name \n"); flock($fh, LOCK_UN); fclose($fh); どなたか詳しい方教えてください。 よろしくお願いします。

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

    こんばんわ、お世話になります。 Perlのファイルロックについて教えて下さい。 色々書き方があるようなのですが、私は下記のように 単純に書いています。 #// ファイルロック開始 flock(LOCK, 2); #// ファイルオープン open(LOG, ">>$data") or exit; #// ファイルへ書き出し print LOG "$now,$ip,$ls\n"; #// ファイルクローズ close(LOG); #// ファイルロック解除 flock(LOCK, 8); 原因かわからないのですが、アクセスが多数同時にあると 10分くらいレスが返ってこなくなったりすることがあるようです。 ファイルロックに精度とかあったりすのでしょうか? 単純に、コードが1500行くらい書いているので、やっている処理自体 重いのかもしれませんが、1アクセスの場合は問題なく返ってくるので どうなのかな…と思い、投稿しました。 論理ファイル(CSV)を呼んで、中のデータを絞り込んでいき その結果をPOSTするいったこと(100ファイル分くらい)をやって います。 ファイルロックによって、パフォーマンスが悪くなったりするのか、 どなたかご教授ください。お願いします。

    • ベストアンサー
    • Perl
  • mkdirでのファイルロック

    私はCGIの経験がほとんどなく超初心者です。下記のようなファイルを作りましたがファイルのロックをしなければデータが書き込まれないようなので困ってしまっています。flockはつかえないようなのでmkdirでロックをかけたいのです。 #! /usr/local/bin/perl $| = 1; require './jcode.pl'; require './mimew.pl'; require './cgi-lib.pl'; &ReadParse(*FORM); $thisfile = 'mother'; $countfile = './mother.txt'; $predatadir ='./mom'; $fromname = "sabra net"; $fromemail = '***@****.co.jp'; $act = $FORM{'act'}; #### main始動 #### if($act eq "indata"){   &getnumber;   &datamod;   &inputDB;   &mailsend;   &view; } else{   &datamod;   &kakunin; } #### main終了 #### #### メッセージ番号設定 #### sub getnumber {   open(COUNTER,"$countfile") || &error('countfileが開けない');     $this_num = <COUNTER>;   close(COUNTER);     $this_num++;   open(COUNTER,">$countfile") || &error('countfileに書きこめない');     print COUNTER "$this_num";   close(COUNTER);   if( length($this_num) == 1 ){     $this_num ="000000" . $this_num;   }   elsif( length($this_num) == 2 ){     $this_num ="00000" . $this_num;   } } #### datafileへ入力 #### sub inputDB {   $datafile = "$predatadir/userdata01.csv";    open(DB,">>$datafile") || &error('datafileに書きこめない');      print DB "$yourname,$email\n";    close(DB); }

    • 締切済み
    • CGI
  • ロック専用ファイルについて

    ロック専用ファイルについて すいません、またまた教えてください。m(_ _)m 一つのページに掲示板とカウンターの2つの別々のコードを含めようとしてます。 (現在、掲示板は問題なく動作していて、掲示板のコードの後に カウンターのコードを書こうとしています。) 掲示板にロック専用ファイルを作って、下記のようにしています。 $lock_fp = fopen("lock.txt", "w"); flock($lock_fp, LOCK_EX); ~掲示板ログの更新処理~ fclose($lock_fp); この後に、カウンターのコードを書いて、同じようにロック専用ファイルを使った 排他ロックの仕組みにしたいと思いましたが、そこでふと疑問が・・・。 flock()の排他ロック開始の行 ~ ロック解除の行(ロックファイルのファイルポインタ破棄の行) の間に書かれている全ての処理は、他の人がアクセスしているときは 自分の番になるまで行われないと思うのですが、 ロック解除の行の後に書かれている他のPHPの処理は普通に進んでいくのでしょうか? だとすれば、カウンター用のロック専用ファイルは 掲示板用のそれ(lock.txt)とは別のもの用意しないといけないと思うのですが、 その考え方で合っていますか? ものすごく基本的な質問な気がするのですが、参考書や参考サイトを見ても なかなか回答を上手に見つけられず困っています。 お手数ですが、ご教授ください。よろしくお願いいたします。

    • ベストアンサー
    • PHP

専門家に質問してみよう