
No.3ベストアンサー
- 回答日時:
>ロックはファイルハンドルが指すファイルにかかっているのですか?
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/ …
――によると「flock() によって作られるロックは、 オープンファイル記述 と関連付けられる」とあるので、厳密にいえばロックとファイルは別物かと。
ロックの存在にかかわらず、ファイルに対するopen()は何度でも実行可能です。
それとは別の話で、ロックによりflock()の実行で処理がブロック(=排他制御)されます。
回答ありがとうございます。
なるほど、ロックされているファイルでも後から自由にオープンできて(ロックとは無関係でこのオープンの時に排他制御は働かない)、後からオープンしたあとそのファイルにロックを試みた時に初めてロックされていたら排他制御されるということですね。
CGIのchatプログラムをいろんな場所から同時に動かしたとして、
最初の人が
open($fh1, "<", $datafile);
flock($fh1, 2);
を実行して、次の人が
open($fh2, "<", $datafile); #--->1
flock($fh2, 2); #--->2
を実行した場合
1の所では$datafileに最初の人がロックをかけててもオープンは自由にできて
2の所で$fh2ファイルハンドルが指す$datafileファイルに対してロックをかけようと試みるが、$datafileに対してロックをかけているファイルハンドルが存在するので2の処理は排他制御により最初の人のロックが解除されるまで待つことになるということですね。
No.2
- 回答日時:
>同じファイルハンドルで別モードで開きなおすことはできますか?
open(FILE, "<", $DATAFILE);
flock(FILE, 2);
open(FILE, ">", $DATAFILE);
――と書いたとき、3行目のopen()は成功しますが、1行目のファイルハンドルFILEはいったんクローズされます。2行目のロックはクローズされたとき解除されます。
open(FILE, "<", $DATAFILE);
flock(FILE, 2);
open(ANOTHER_FH, ">", $DATAFILE);
――なら別です。異なるファイルハンドル指定であれば、1行目のFILEはクローズされてませんので、2行目のロックはかかってます。
また、問題なくopen()は成功します。何度でも。回答No.1はこの意味です。
3行目で$DATAFILEは空になります。
下記はサンプル。コメントアウトを外すと挙動が変わります。
system( 'echo OK >a.txt;cat a.txt' );
my $f1, $f2, $f3;
open( FH, '<a.txt' ) or die; $f1 = fileno( FH );
flock( FH, 1 ) or die;
#if ( fork() == 0 ){ sleep 5; exit( 0 ); }
#open( F2, '<a.txt' ) or die; $f2 = fileno( F2 );
#flock( F2, 1 ) or die;
#print "F2:",scalar( <F2> );
open( FH, '>a.txt' ) or die; $f3 = fileno( FH );
flock( FH, 2 ) or die;
print "FH:",scalar( <FH> ),"\n";
printf "fileno: FH=%d,F2=%d,FH(re)=%d\n", $f1, $f2, $f3;
system( 'cat a.txt' );
回答ありがとうございます。
すいません私にはちょっと難しくてサンプルを理解できませんでした。
ロックはファイルハンドルが指すファイルにかかっているのですか?
そうだとすると別ファイルハンドルで同じファイルを開こうとするとロックがかかっていて開けないと思うのですがどうでしょうか。
もしかして同じプロセス内からだとロックをかけたファイルでも別ファイルハンドルで開くことができるということでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlのプログラミング 部分入れ...
-
Perlでファイルの末尾から指定...
-
テキストファイルで提出とは?
-
perl の open について教えてく...
-
Perl言語について。
-
ファイルをディレクトリ分配の...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlについて
-
perlのrequireの動き方について...
-
perlの構文でカンマの意味が分...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
where can I buy snowbord in t...
-
close()で例外が投げられる理由
-
改行コードが勝手に
-
perlのflock関数でロックをかけ...
-
open中のファイルをrename
-
telnet接続
-
cgiログファイルの書き込みに余...
-
ファイルから読み込んだ文字を
-
die関数のエラー出力先について
-
テキストファイルの本文中に行...
-
ジョブショップスケジューリング
-
GD.pmで作成した画像を保存する...
-
巨大ファイルの行をを逆順に並...
-
ファイルの入出力
-
ExcelをCSV書き出す場合のシー...
-
エクセルVBA コードが同じでも...
-
awkスクリプトでダブルクォーテ...
-
batファイルでrenameができませ...
-
VBAでCSVファイルを途中行まで...
-
Windowsで複数のファイルを同じ...
おすすめ情報
質問があいまいでした。
1.openで開いたファイルをcloseで閉じないで、同じファイルハンドルで別モードで開きなおすことはできますか?
2.1が可能なら最初にopenした時にロックをかけていた場合、開きなおしたときにロックは継続されていますか?
よろしくお願いします。
理解できたと思って、プログラムを修正したのですが、チャットを打つとデータが消えてしまいます。
修正した内容は次の通りです。
open($fh1, "<", $DATAFILE);
flock($fh1, 2);
・・・データを読み込みそれに変更を加える・・・
open($fh2, ">", $DATAFILE);
・・・データの書き込み・・・
close($fh2);
close($fh1);
次のように修正したらデータが消えることはなくなりましたが、
同時に書き込まれた時のロックが正しく機能してるかどうかは検証してません。
(検証の仕方がわからない)
if (! -f $DATAFILE) {
open(FH, ">", $DATAFILE);
close(FH);
}
open(FH, "+<", $DATAFILE); # データファイルを読み書きモードで開く
flock(FH, 2); # ロックをかける
・・・データを読み込み修正する・・・
seek(FH, 0, 0);
・・・データを書き込む・・・
truncate(FH, tell(FH));
close(FH); # closeと共にロック解除
これで問題ないでしょうか