
ファイルロックにflockを使っているのですが、複数のファイルを扱うので、データファイルにロックをかけるのではなく別途「ロックファイル」に対してロックをかけています。
データファイルであれば読み書きモードで開く必要がありますが、ロックファイルは中身はどうでも良いので、
open(LOCK,"> $lockfile") or die ~
というように上書きモードで開いて良いとする解説を読んだので、そのようにしています。
しかし、ごくたまにロックファイルが消えてしまう現象が発生します(なかなか再現できずに条件など特定できず)。
あくまでもファイルの中身が壊れるとかいうことではなくて、ファイルそのものが消えます。
そこでお聞きしたいのですが、
1.
ロックをかけたファイルが何らかの原因で消えた場合、ロック状態も消失してしまう(他プロセスがロックできてしまう)のでしょうか?
試してみたのですが、
まずプロセスAがロックをかけて
プロセスBが同ファイルにロックをかけようとすると、失敗する
プロセスAがロック解除せずにファイルを削除する
それでもプロセスBはロックに失敗する
プロセスAが(もう存在しないファイルの)ロックを解除(close)する
するとプロセスBはロックに成功する
ということは分かったのですが、上記を、プロセスAがファイルを削除した後にプロセスBを動かすと、どういうわけかロックに成功してしまいます。
2.
複数プロセスが同時に上書きモードでopenしようとするのが消える原因なら、ロックファイルであってもやはり読み書きモードで開くべきなのでしょうか。そしてそれなら消えることは無いのでしょうか。
(読み込みモードではロックできないという解説もありました。)
御教授のほどよろしくお願いいたします。
A 回答 (4件)
- 最新から表示
- 回答順に表示

No.4
- 回答日時:
私もサイトをもってるけどそんなにアクセス数がないので、そのような状況を見たことがないので、予想ですけど、
上書きモードだと、開いてから、ファイルサイズを0にする時間帯で、別プロセスがアクセスすると存在しないかのような動作になると言うことでしょうか?
とすれば、読み書きモードでのopenは、ファイルサイズ変更の手間が短縮されるので、読み書きモードにするのが最良と言うことになるでしょう。
ご回答ありがとうございます。
ファイルは、「存在しないかのような動作になる」と言うより、実際に消えてしまいます。
この条件などはまだ特定できていませんが、どうやらそれらしい情報を見つけたので、とりあえず暫定的に、消える原因は「上書きモードでの同時複数オープン」のようです。
それは良いとして、いずれにしてもロック中にファイルが消えると問題が起きることが、No.1の1のご回答でわかりました。
そこで2ですが、可能性はともかく少しでも安全なものを作ろうとすれば、
●ファイルが消えない
●排他ロックもできる
という点では、やはりおっしゃるように
open(LOCK, "+< $lockfile")
のように読み書きモードが良さそうですね。
No.3
- 回答日時:
たんにこんな感じとか:
use strict;
use Fcntl ':flock';
my $fn_lock = 'a.lck';
open( LCK, $fn_lock ) or die "?! [$$]open: ${fn_lock} - $!,"; # readonlyでオープン。
flock( LCK, LOCK_EX ) or die "?! [$$]flock: $!,";
print '[',$$,']lock',"\n";
sleep( 1 );
print '[',$$,']unlock',"\n";
close( LCK ) or die "?! [$$]close: $!,";
これでファイルが消えるようだったら、なんか別のところが悪いと思われ。
ご回答ありがとうございます。
何度もすみませんが、読み込みモードで開くと排他ロックできない環境があるので・・・。
やはり
open(LOCK, "+< $lockfile")
のように読み書きモードが良いということですかね・・。

No.2
- 回答日時:
>どこかのページ(URLなど失念)で、読み込みモードでは排他ロックがかからない環境がある、というようなことが書かれていたので
http://homepage1.nifty.com/glass/tom_neko/web/we …
ここの解説にありました。
Solarisでは、読み込み専用モードで開くと以下の書き込みロックしか出来ずに、別プロセスに読み出されてしまうらしいです。
flock(XX, 1) 読込中なので書込をロック、あとから来たら待つ。(ブロック)
同じ解説ページの「まとめてロックする」方式がロック専用ファイル利用法として有効のように思います。
>「読み込み専用(readonly)なファイル」
これは、ファイル属性を 444 =readonly にすると云うことでしょう。
こうしておけばプログラムからの削除や変更は出来ません。
でも、読み書きモードでのオープンも出来ないけど。
参考URL:http://homepage1.nifty.com/glass/tom_neko/web/we …
ご回答ありがとうございます。
Solarisということは、やはり下にも書いたようにfcntl実装の場合ということですね。
> 同じ解説ページの「まとめてロックする」方式がロック専用ファイル利用法として有効のように思います。
恐れ入りますが、これは質問文にも書いた方法と同じで、場合によってファイルが消えてしまうようでして…。それが今回させていただいた質問でした。
やはり
open(LOCK, "+< $lockfile")
のように読み書きモードが良いのでしょうか。
No.1
- 回答日時:
1. 関数flock()は、ファイルハンドルを通して、ファイルにロックをかけますので、ファイルが削除されて新たなファイルが作成された場合、別物になります。
2.たんにロックをかけるだけなら、読み込み専用(readonly)なファイルでもできます。
プログラム内でのファイル削除によるロック失敗が発生しませんので、こっちがおすすめ。
ただし、あらかじめファイルを作成しておく必要があります。
ご回答ありがとうございます。
1については、つまりプロセスBがファイルハンドルを取得した時点でファイルが存在していれば、その後でプロセスAがファイルを削除しても両プロセスとも同じファイルハンドルなので、削除後もロックが有効で、ファイルハンドル取得時にファイルが削除されていたら、同じファイルパスであってもロックがかかっていても、別物になる、ということですね。
ということは、やはり削除されてしまうと問題ありということですね。
2についてなのですが、恐れ入りますが「読み込み専用(readonly)なファイル」とは、読み込みモードでオープンしたファイル、と理解して良いでしょうか。
その場合ですが、どこかのページ(URLなど失念)で、読み込みモードでは排他ロックがかからない環境がある、というようなことが書かれていたので・・・。
システムコールがflockではなくfcntlで実装されている場合なのかな?と漠然と思ったのですが、少なくともlockfなど共有ロックもサポートされている環境という前提で、やはり
open(LOCK, "+< $lockfile")
のように読み書きモードが良いのでしょうか。
open(LOCK, "+> $lockfile")
と書くとオープン時にファイルへの影響の危険性から、より安全なのは前者ということでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(Microsoft Office) OneDrive Personalについて 1 2022/08/02 18:25
- Android(アンドロイド) Googleのファミリーリンクの危険性に気付いてしまったのですが、皆さんの感想を教えてください! 2 2023/05/09 10:01
- Perl perlのflock関数でロックをかけたままopen関数で何度もファイルを開きなおすことはできますか 3 2023/05/01 22:25
- 格安スマホ・SIMフリースマホ Y!モバイル転出後のSIMロック解除後 1 2023/01/09 20:14
- docomo(ドコモ) SIMロック、またはSIMロック解除の仕組みをおしえてください。 5 2022/04/25 10:57
- 格安スマホ・SIMフリースマホ SIMカードのロックについて 1 2022/03/29 15:02
- UNIX・Linux shellscript内のコマンドを、sudo(toor)として実行 2 2022/09/23 15:05
- その他(車) ドライブレコーダー 5 2022/06/08 15:23
- iPhone(アイフォーン) iPhone セキュリティロック解除 2 2023/01/26 18:59
- docomo(ドコモ) ガラケーの電池ロック。過充電について。 4 2023/05/11 08:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
VBScriptでのファイル結合処理...
-
バッチシステムの処理時間
-
EXEファイルに画像ファイルの埋...
-
gccでリソースファイルを使わな...
-
ファイルの結合
-
csvファイルを開かずに文字を検...
-
cvSnakeImageのエネルギー表示...
-
SSIを使わずに・・・
-
javaでMIDIファイルの取り出し...
-
この問題のファイルを読み込ん...
-
VC++でのiniファイルの読み書き
-
PDFを全文検索するプログラム
-
パワーポイントの画面表示が点...
-
unlinkしたファイルを元に戻す...
-
iniファイルに追記がしたいです。
-
static な c 関数の unit-test ...
-
バッチで118項目のCSVを処理し...
-
COM相互運用機能のON,OFFによる...
-
Tifファイルの数値化について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
dataファイルをxtxファイルにす...
-
csvファイルを開かずに文字を検...
-
ファイル名の先頭にアンダース...
-
CSVファイルへの保存の際、デー...
-
グローバル変数のよくない使い...
-
バッチで118項目のCSVを処理し...
-
テキストファイルの最終行を削...
-
VBAにてEXCEL以外のファイル(テ...
-
VBに、Cのincludeのようなもの...
-
分割コンパイルの#defineについて
-
RPGでファイル名(もしくはレコ...
-
SGファイルって何ですか?
-
マウスポインタの変更
-
Excelマクロでの再読込み方法
-
【C#】リソースファイルの埋め...
-
ダイアログボックスで複数フォ...
-
C言語のfopenについて教えてく...
-
ドラッグアンドドロップでファ...
-
「VBScript」ADODB.Streamにお...
おすすめ情報