• ベストアンサー

排他処理について

http://www.tryhp.net/lock.htm このサイトの排他処理を参考に組んでいるのですが、 「7.完成」のソース、「#ロックされていなければロックする」以降に出てくる$tmpfileについての質問です。 この変数$tmpfileにはテンポラリ用にこちらで用意したファイル名が入っているということでしょうか? リネームするのであれば rename($tmp_dummy,$datafile); かなと考えていたのですが…。 ソース上部でも$tmpfileのテンポラリを作成していないので不思議です。 意図が読めずに困っております。お知恵を拝借したいと思います。

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

ご推察のとおり、$tmpfile には全プロセスで共通になる名前が どこかで設定されているのでしょう。 > ソース上部でも$tmpfileのテンポラリを作成していないので不思議です。 作ってますよ。 .7でいうなら if (link($tmp_dummy,$tmpfile) == 1) { この link で作ってます。 より正確には、$tmp_dummyの中身を共有する $tmpfile という名前でアクセスできるように リンクを作成している。のですが。 > リネームするのであれば > rename($tmp_dummy,$datafile); 上述のとおり、$tmp_dummyと $tmpfileの実体は同じです。 ここで$tmp_dummyを使って renameしようとすると、 このrename を囲む foreach を renameして抜けたときに $tmp_dummyという名前のファイルがなくなってしまうので > unlink $tmp_dummy; #プロセステンポラリーを削除する ここでちょっと引っかかります。 なので > rename($tmpfile,$datafile); $tmpfileからrenameしているというわけです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • bgbg
  • ベストアンサー率53% (94/175)
回答No.1

$tmpfileはロックの有無を判定するためだけのファイルなので、他のファイルと名前がかぶらなければどんな名前でもいいです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • flock関数での排他制御

    外部ファイルを更新する処理を作成しています。 ファイル更新中にファイルロック(flock関数)をかけて、 ロック中という事ではじかれた場合はエラーを出力するという仕組みを考えています。 下記にように記述しているのですが、 ロック中で書きこめなかった場合 エラーを出力する事はできたのですが、 ファイルが全て消えてしまいます… この場合はファイルを元のままに保持していたいのですが… あつかましいお願いかとは思いますが、 以下のソースで訂正すべき箇所は何処でしょうか。 =============================    $fp = fopen ($filename, 'w');  // ファイルオープン    if (flock($fp, LOCK_SH)) {   // 排他的ロックを行う    fputs($fp, 'ABCD');    // 書込む    flock($fp, LOCK_UN);    // ロックを解放する    fclose ($fp);       // クローズ        $flg = 1;   // 書込フラグ    b

    • ベストアンサー
    • PHP
  • CSVを使ったパスワード変更処理について

    CSVを使ったパスワード変更処理について 以下のソースをどういじれば変更が可能か申し訳御座いませんが、 どなたか分かるかたご教授願いますでしょうか? $post = $_POST; $org_file=fopen("logindata.csv","r"); $tmp_file=fopen("guest.tmp","w+"); flock($org_file,LOCK_SH); flock($tmp_file,LOCK_EX); $line =date("Ymd-H:i:s").","; $line.=$_POST['mail'].","; $line.=$_POST['pw2'].","; fputs($tmp_file,$line."\n"); while($row=fgets($org_file,1024)){ if($temp[1]==$post['mail'] && $temp[2]==$post['pw']){ } else{ fputs($tmp_file,$row); } } flock($tmp_file,LOCK_UN); flock($org_file,LOCK_UN); fclose($tmp_file); fclose($org_file); unlink("logindata.csv"); rename("guest.tmp","logindata.csv"); echo "パスワード変更しました。"; exit;

    • 締切済み
    • PHP
  • LOCK_EXはifの条件になり得るのか?

    $fp = fopen("/tmp/lock.txt", "r+"); if (flock($fp, LOCK_EX)) { // 排他ロックを確保します ftruncate($fp, 0); // ファイルを切り詰めます fwrite($fp, "ここで何かを書きます\n"); fflush($fp); // 出力をフラッシュしてからロックを解放します flock($fp, LOCK_UN); // ロックを解放します } else { echo "ファイルを取得できません!"; } fclose($fp); PHPのマニュアルサイトに書いてあった例文なのですが、たぶんロックできなかった場合は「ファイルを取得できません!」に出るようにするというものだと思います。 ただ、LOCK_EXはロックできない場合は、ロックできるようになるまで待ちますよね? だとすると、このif文ってelseは機能しないと思うんですが、どうなんでしょうか? もしかしてLOCK_EXは時間制限があって、待ち状態が何分も続くとタイムアウトとしてFalseを返す? そのときにelseが動くということでしょうか? この例文の下にLOCK_NBを使ったものもあるので、LOCK_EXの動作を勘違いしてるとは思えません。 この例文はどのタイミングの時にFalseを返して、elseが動くのでしょうか? http://php.net/manual/ja/function.flock.php

    • 締切済み
    • PHP
  • メッセージが上に追加される掲示板

    Perl超初心者ですが、お願いいたします。 掲示板(本当は、友人の原稿をホームページに自分で載せてもらうスクリプト)を、だいたい以下のように組んでみました。 require "cgi-lib.pl"; require "jcode.pl"; $naiyou = $in{"naiyou"}; &ReadParse;&jcode'convert(*naiyou,"euc"); $datafile="data.txt"; $tempfile="hokan"; open (TEMP,">$tempfile"); print TEMP "<font size=\"2\">$naiyou</font>"; open(DATA,"$datafile"); while (<DATA>) { print TEMP $_; } close(DATA) ; close(TEMP) ; rename($tempfile,$datafile); ところが、ローカルでは動いたものの、私が借りた、CGIを使える無料のサーバーでは、パーミッションを777に設定できません。(詳しい説明がないのですが、他のユーザーに書き込み権限を与える設定はどれも駄目そうです) そこで、リネームを使わないで、上に追加していくスクリプトを作れないものでしょうか。無理ですか? サンプルがあるホームページなどを紹介していただけるとうれしいです。

    • ベストアンサー
    • Perl
  • csvの内容を配列に入れて個別に変数をつける

    はじめまして、お世話になります。 内容はdata.csvを開いて$a1の値が、ban1の時に、 該当の一行を読み出して、カンマ区切りでわかれている順番に、 $a1 $a2 $a3という変数に代入して他のプログラム内で、利用できればと思いますが、 思うように値が取得できません。 下記、参考サイトなどを見ながら、 動作の部分をかいてみました。 まだ理解が浅く、見当はずれな指示があるかもしれませんが、 ご参照いただき具体的な、 ご指摘をいただければと思います。 よろしくお願いいたします。 my $dataFile = 'data.csv'; open FH,"<$dataFile" or error_msg("データファイルが開けません : $!"); flock(FH, LOCK_EX); while(<FH>){ chomp(); my@dummy = split(/,/,$_); if($a1 == $ban1) { $hoge = $_; last; } chop $hoge; ($a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$a10,$a11) = split(/,/); } flock(FH, LOCK_NB); close FH;

  • ファイルの読み書きについて教えてください。

    フォームから投稿されてきた内容を、テキストファイルに書き込む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
  • Verilog-HDLによる設計において

    現在Z8085のCPUを設計しており、テンポラリレジスタにラッチする部分でなかなか上手くいきませんので質問させていただきます。 always文を使用したステートマシンにより制御しようとしているのですが次のようなWarningが出ます。 Warning: Latch IR[0]$latch has unsafe behavior Warning: Latch IR[1]$latch has unsafe behavior            : Warning: Latch IR[7]$latch has unsafe behavior Warning: Latch TMP1[0]$latch has unsafe behavior Warning: Latch TMP1[1]$latch has unsafe behavior            : Warning: Latch TMP1[7]$latch has unsafe behavior Warning: Latch TMP2[0]$latch has unsafe behavior Warning: Latch TMP2[1]$latch has unsafe behavior            : Warning: Latch TMP2[7]$latch has unsafe behavior Warning: Latch NEXT_STATE[0]$latch has unsafe behavior Warning: Latch NEXT_STATE[1]$latch has unsafe behavior <ソース> module CPU_TMP( CLK, nRST, FROM_DCD, IR, TMP1, TMP2, STATE, NEXT_STATE ); input CLK;//クロック input nRST;//リセット input [7:0] FROM_DCD;//入力命令 output [7:0] IR;//命令レジスタ output [7:0] TMP1;//テンポラリレジスタ1 output [7:0] TMP2;//テンポラリレジスタ2 output [1:0] STATE;//現在のステート output [1:0] NEXT_STATE;//次のステート reg [7:0] IR; reg [7:0] TMP1; reg [7:0] TMP2; reg [1:0] STATE; reg [1:0] NEXT_STATE; //状態 parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter SD = 2'b11; //命令 parameter INRA = 8'h11; parameter MVIA = 8'h22; parameter JMP = 8'h33; always @( posedge CLK ) begin     if( nRST == 0 )       STATE <= SD;     else       STATE <= NEXT_STATE; end always @( STATE ) begin    case( STATE )      SD : begin            IR <= 0;            TMP1 <= 0;            TMP2 <= 0;            NEXT_STATE <= S0;          end      S0 : begin            IR <= FROM_DCD;            case( FROM_DCD )              INRA : NEXT_STATE <= S0;              MVIA : NEXT_STATE <= S1;              JMP : NEXT_STATE <= S2;            endcase          end      S1 : begin              TMP1 <= FROM_DCD;              NEXT_STATE <= S0;          end      S2 : begin              TMP2 <= FROM_DCD;              NEXT_STATE <= S0;          end endcase end endmodule どのようにしたらこのWarningを消すことができるでしょうか。

  • 排他処理について

    あるシステムの、(CGIアプリケーションの)ログファイルの機能ですが、 ログのサイズが指定のサイズに達したとき、 バックアップファイルとしてリネームし、また新たにファイルを作成する...という処理があります。 (1)ファイルのサイズは CFile::GetStatus( FileName,fs ) で、 で、fs.m_size を取得しています。 (2)fs.m_size >= (指定のサイズ)になったときに 拡張子を .bakに切り替え(rename)ています。 ・・・ということで、同じ処理で2つのログファイルができ、.bakは指定のファイルサイズ程度で 残っているはずだったのですが。。。 複数プロセスが同時に動くことがあり、排他がかかっていないため、 複数プロセスで、ファイルサイズが指定のサイズをオーバーしたと判断し、 続けて(!?)リネーム処理が行われ、 .bakファイルも小さなファイルになってしまう事が発生しました。 これを防ぐには、排他が不可欠とはわかるのですが システムに一番影響なく、訂正するにはどのような方法があるか アドバイスしていただけないでしょうか。 かなりアクセスの多いシステムなのであまり、重たくなるような修正はできないのです。 ファイルサイズがオーバーしたときに overflg用のファイルを作成しておき、 ・そのファイルがあったら他のプロセスは何もしないで普通に書き込む  (書き込む時には排他がかかっています) ・そのファイルが無かったら、普通にファイルに書き込む  (ファイルサイズは多少オーバーしても問題はありません) ・renameが終わったら、そのoverflg用ファイルを削除する のようなことを考えたのですが、実用的でしょうか? よろしくお願いします。

  • 排他処理について教えてください。

    現在、ガンダムカルトQQQ(MIDI-CG-SOFT-総合サイト)【http://ha1.seikyou.ne.jp/home/jun/】様よりフリーで配布されている「QQQ MEMBERS ver1.00」を使用してメンバー管理を行なっています。 しかし、このスクリプトには排他処理が入っていなかった為、ディスカバリーシステム【http://www.dscvsys.com/Perl.htm#filelock】様のページを参考にrenameを使った排他処理を作成しましたが、どこに排他処理をかけていいかわからず、かなり悩んでいます。 *排他処理はディスカバリーシステム様の記述をそのまんま使用しています。 尚、ファイル構成は以下の通りです。 cgi-bin  |  ├member.cgi  ├jcode.pl  └lockdir    └lockfile(拡張子無しテキストファイル) 大変申し訳ありませんがご教授宜しくお願い致します。

    • ベストアンサー
    • CGI
  • 排他処理について

    VBでトランザクションをかけてあるテーブルを処理しています。 具体的にはテーブルAのレコードを一時的に別テーブル(テーブルB)に コピーしてそのレコードすべてを元のテーブルから削除して、 テーブルB内で処理をさせてから、そのデータをテーブルAに戻して コミットしています。 この処理中に、別PGもしくはSQLPlusでテーブルAからテーブルBに コピー対象の1レコードを削除してコミットしました。 これってエラーになる?ならない?それともトランザクション中だから テーブルAがコミットされて開放されるまで待ちの状態になる?? 実際どうなったかというとエラーにならなくて、その処理で最後に テーブルAにテーブルBをコピーしたときにエラーになって データがきえるという現象がおきてしまいました。 上記のような処理のときにOracle条ではどのような処理になるのでしょうか? よろしくお願いします。