ファイルを開いてロックし、そのロックを競合している別のプロセスが切り捨てられたファイルを見る可能性なしに切り捨てたいようです。これにはいくつかの制限があります。
- 切り捨ての前にロックを取得する必要があります。これは、ロックを取得する前に切り捨てを行うため、最初の解決策を除外します。
- ファイル ハンドルを別のモードで再度開くことはできません。そうしないと、ロックが失われます。これは、切り捨てを再開しても実行できないことを意味します。
したがって、理想的なソリューションには次の手順があります。
- ファイルは切り捨てられずに開かれます。たとえば、sysopen やオープン モード
>>
を使用します+<
。ここでは、sysopen オプションO_TRUNC
やオープン モードなどを使用してはなりません。>
+>
- ロックが取得されます。
- 切り捨てが実行されます。
open
新しいファイルハンドルを作成する場合と同様に、ここでtruncate
関数を使用する必要があります。
- ファイルが追加モードで開かれた場合は、ファイル
seek
の先頭に必要です。
最初の解決策は、ロックを取得する前に切り捨てられるため、除外できます。
2 番目と 3 番目の解決策はどちらも可能ですが、seek
必要ありません。
他のソリューションは regular を使用できますopen
:
open my $fh, "+<", $file; # Achtung: fails if the file doesn't exist
flock $fh, LOCK_EX;
truncate $fh;
# or:
open my $fh, ">>", $file;
flock $fh, LOCK_EX;
truncate $fh;
seek 0, 0;
多くの場合、関係のないファイルをロックとして使用することをお勧めします。これにより、再オープンの問題を回避できます。これは次のようになります。
# adapted from perldoc -f flock
sub lock {
my $file = shift;
open my $fh, "<", ".$file.lock";
flock $fh, LOCK_EX;
return $fh;
}
sub unlock {
my $fh = shift;
flock $fh, LOCK_UN;
}
my $lock = lock($file);
open my $fh, ">", $file;
...
unlock($lock);
もちろん、関連するすべてのプロセスは、このインターフェイスを尊重し、適切なロックファイルを作成する必要があります。