たいていの場合は問題ないのですが、
アクセスカウンタ等の更新の激しい物の場合、
file()やfile_get_contents()でファイルを開き、
その内容を元にfopen()・flock()・fputs()等を使って書き込むと、
データが破損してしまう事があります。
これはロック中でもfile()等では開けてしまうのが原因だと思いますが、
file()等を使う際の排他処理はどのようにしたら良いのでしょうか。
ロック中は、fopen()の前で解放されるのを待つ仕様なようなので、
$fp=fopen("ロック用ファイル","r");
flock($fp,LOCK_EX);
~複数のファイルの読み書きを含めた、様々な処理~
fclose($fp);
としてみたのですが、これで排他処理は完璧になるでしょうか?
これまでは、
1. ロック用ファイルが存在する場合、なくなるまでsleep()
2. 空のロック用ファイルを作成
~複数のファイルの読み書きを含めた、様々な処理~
3. ロック用ファイルを削除
としていたのですが、これでは度々破損してしまいました。
「1」と「2」の間で、新しいプロセスが「1」に割り込んで来てしまうせいでしょうか。
そうだとすれば、fopen()とflock()の間でも
同じ事が起きてしまう気がするのですが、どうなんでしょうか。
No.2ベストアンサー
- 回答日時:
おや?だめですか?
では「大人のCGIスクリプト」という本で紹介されていた方法
ファイルが飛ばないようにするには
:ダブルファイルを用いて、両方の更新時間を比較
:更新時間の新しい方のデータを読んで、古い方に書き込む
:よって、データは交互に書き込まれる。
カウンターなら、これだけでもデータが飛ばなくなる
とありました。
あと、以前のQAで、一時ファイルに書き込んでからrenameを使う方法が紹介されてました。
掲示板用ならこちらがよいかもしれません。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1677355
それでもかち合うアクセス数は私にはイメージが付かないので、参考にならないかもしれませんが。
シグナルについてはphpでは、このへんかな?
pcntl_signal -- シグナルハンドラを設定する
http://www.php.net/manual/ja/ref.pcntl.html
お使いのサーバーで有効になってるかどうかも調査する必要がありそうです。
この回答への補足
ご丁寧に有り難う御座います。
今のところはロック用ファイルを用意して、それをflock()する事で破損を防げているようです。
土日に破損する事が多いので、もう少し様子見してみようと思います。
ご教授頂いた交互に書き込む方法も良さそうですね。
ただ、この方法だけでは複数のプロセスで同じデータを扱ってしまう可能性があり、
結局は別途に排他処理を行う必要がありますね。
rename()も同じでファイルを開く際に別途ロックを行わなければいけませんね。
シグナルの件ですが、素人の私には結構難しそうです^^;
色々もっと勉強しないといけないみたいです。
でも、モジュール版ではその関数は使えないようですので、関係ないようですね。
有り難う御座いました。
時間が空いてしまい、申し訳御座いません。
結局、先週の土曜日に破損してしまいました。
見た目、flock()を使った方法に問題は見受けられないんですが・・・。
フラグが残ってしまった場合の対応が曖昧ですが、とりあえずmkdir()も加えてみようと思います。
トップページで使用しているため、出来ればsleepは避けたい気持ちがあるのですが・・・
No.1
- 回答日時:
symlinkかmkdirの方がよいそうです。
参考 web と CGI のひみつ >> 排他処理
http://x68000.q-e-d.net/~68user/webcgi/lock.html
参考URL:http://x68000.q-e-d.net/~68user/webcgi/lock.html
アドバイス有り難う御座います。
これまでにPerlカウンタ等でmkdir()やsymlink()を使っていたのですが、
それでも度々データが破損してしまいました。
参考サイト様によると、シグナルが原因のようですが、
これはモジュール版PHPでも言える事なのでしょうかね。
mkdir()やsymlink()を使った時に
フラグが残ったままになってしまった場合の処理方法がよく分かりません。
単にsleep(1)を5回繰り返してダメならフラグ削除、というのでは問題アリだと思うので。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Perl perlのflock関数でロックをかけたままopen関数で何度もファイルを開きなおすことはできますか 3 2023/05/01 22:25
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- Visual Basic(VBA) vbaの構文の修正相談(xmlファイルを順に開いてコピペ作業) 1 2023/04/22 01:18
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- その他(Microsoft Office) OneDrive Personalについて 1 2022/08/02 18:25
- その他(コンピューター・テクノロジー) <a href="file:///フォルダ名/ファイル名">リンクテキスト</a>について 1 2023/04/06 22:40
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・ハマっている「お菓子」を教えて!
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
お気に入りのアイコン変更教え...
-
FTPコマンドでディレクトリごと...
-
フォントの色を変えるには?
-
【WordPress】メディアの一覧出力
-
移動元のURLを変数に取りたい
-
ツリーメニューを縮小させたい
-
makefile でファイルをコピーす...
-
PHPで複数ファイルのダウン...
-
a.phpにあるアクセスカウンター...
-
PostMail
-
拡張子php画像をjpg画像等に変...
-
ボタンのクリック数を合計保存...
-
PHPのif文でその処理を途中で抜...
-
AN HTTPDでPHPが動かない
-
フォームで戻った際に入力済み...
-
phpでファイルを読み込んで保存...
-
jqueryの$.ajaxでPHPに値を渡し...
-
ページに読み込みたい
-
PHPの会員登録システムのエラー...
-
PHPがLocalhostのフォルダ内で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Smarty tplで定数値を使用でき...
-
is_fileでファイルが存在してい...
-
datファイル
-
cakephp views/pagesの中にイ...
-
MovableTypeでカテゴリー、月別...
-
chmod()で所有者が変わってしまう
-
phpを使った外部ファイル化を・...
-
phpをhtmlのように編集...
-
文字コードが混在するテキスト...
-
サーバー内のファイル一覧をWeb...
-
tmpファイルが消えない
-
header(Location: next.php) だ...
-
PHPのif文でその処理を途中で抜...
-
フォントの色を変えるには?
-
FTPコマンドでディレクトリごと...
-
onedrive にexcelファイルをア...
-
3つ以上の論理積は利用可能なの...
-
.phpと.incファイルの違いはな...
-
VBSの「MsgBox」について
-
リンク先を隠す方法はないでし...
おすすめ情報