
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で質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- Windows 10 .dvi の file が開けません 0 2023/05/06 11:23
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- Ruby 教えてください 2 2023/01/04 17:50
- Visual Basic(VBA) vbaの構文の修正相談(xmlファイルを順に開いてコピペ作業) 1 2023/04/22 01:18
- その他(プログラミング・Web制作) Fortranでの出力ファイル 2 2023/03/21 21:25
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Visual Basic(VBA) vba メモリ節約 3 2022/09/16 21:45
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
while(<ハンドラ>) {} で行数を...
-
改行コードが勝手に
-
close()で例外が投げられる理由
-
open中のファイルをrename
-
perlのflock関数でロックをかけ...
-
PICでFatFsでオープンした内容...
-
Perl:ファイルハンドルをスカラ...
-
perlで複数のファイルの処理に...
-
die関数のエラー出力先について
-
Perl で syntax error
-
Perlでログファイルからユーザ...
-
バッチファイルの作り方(CSV→...
-
VBAでCSVファイルを途中行まで...
-
エクセルVBA コードが同じでも...
-
Windowsで複数のファイルを同じ...
-
VB6.0でDB接続する際に切断時の...
-
画像がテキスト表示になる。
-
1行がやたら長いテキストをバッ...
-
MySQLにバイナリデータを正常に...
-
batファイルでrenameができませ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
close()で例外が投げられる理由
-
AutoCADのスクリプト
-
改行コードが勝手に
-
open中のファイルをrename
-
perlのflock関数でロックをかけ...
-
perlでファイル内の文字列を置...
-
Perlでのファイル一括読み込み
-
巨大ファイルの行をを逆順に並...
-
ファイルの入出力
-
perlで大容量CSVのsort方法につ...
-
パスワードを外部ファイルから...
-
Perl cgi 編集&削除
-
オープンしたファイルで行の連結
-
PICでFatFsでオープンした内容...
-
パスワード自動生成スクリプト...
-
die関数のエラー出力先について
-
Perlでファイル出力時にデッド...
-
perlでURLから画像ファイルを作...
-
ハッシュにファイルハンドル
-
パイプをopenして/usr/bin/grep...
おすすめ情報
質問があいまいでした。
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と共にロック解除
これで問題ないでしょうか