4

完全に書き込まれる前に、このファイルを探しに行く可能性のある他のプロセスが読み取りを開始しないように、作成時に読み取りに対してロックされるファイルを作成する必要があります。

作成してロックできることはわかっていますが、競合状態になる可能性があるのではないかと心配しています。

それとも私はここで何も心配していませんか?ファイルを書き込み用に開いてから、別のプロセスで読み取り用に開いた場合、書き込みプロセスがファイルを閉じるまで、読み取りプロセスは EOF を認識しませんか?

4

3 に答える 3

8

との競合状態がありますが>>>を使用して回避できます+<

# >
open(my $fh, '+<', $qfn) or die $!;
flock($fh, LOCK_EX) or die $!;
truncate($fh, 0) or die $!;
...

# >>
open(my $fh, '+<', $qfn) or die $!;
flock($fh, LOCK_EX) or die $!;
seek($fh, 0, SEEK_END) or die $!;
...

説明するシナリオには競合状態もあります。

Writer                       Reader
=========================    =========================
- opens file
                             - opens file
                             - locks file
                             - obtains lock on file
- locks file [blocks]        - reads the file [empty]
                             - closes and unlocks file
- obtains lock on file
- writes to file
- writes to file
- closes and unlocks file

この問題を回避するための一般的な戦略は、ライターを雇うことです

  1. 一時ディレクトリにファイルを作成してから、
  2. renameファイルが完成したときにリーダーが監視するディレクトリにファイルを追加します。

renameはアトミックアクションであるため、ファイルはリーダーが監視するディレクトリに完全に形成された状態で表示されます。これにはライターの協力が必要ですが、最善の解決策はそうなります。

于 2011-06-17T14:50:49.060 に答える
8

umask(0777)ファイルを作成する前に使用します。

----------ファイル システム内のファイルのエントリは、ファイル ハンドルがまだ書き込みを許可している場合でも、完全にアクセスできなくなります[*] (つまり、アクセス権)。

次にchmod()、完了したらファイルを次のようにします。

my $file = 'foo.txt';
my $umask = umask(0777);    # change the umask
open(OUT, '>', $file);      # create the file 
umask($umask);              # reset the umask
print OUT "testing\n";      # put stuff in your file
close(OUT);                 # finished with that...
chmod(0644, $file);         # change the permissions

注意: これは実際には厳密な意味での「ロック」ではなく、オペレーティング システムがファイルへのアクセスを積極的に防止します。これはファイル システム レベルの「ハック」です。ファイルを実際に開くことができない場合、そのファイルは一種のロックされています。

[※]root加工を除く。

(FWIW、半分書き込まれたファイル読み取ると、EOF 状態になります。)

于 2011-06-17T14:29:35.583 に答える
3

これは、お使いのオペレーティング システムでサポートされているか、サポートされていません。もしそうなら、それは簡単で簡単です。

use Fcntl   qw( O_CREAT   O_EXCL   O_WRONLY   O_EXLOCK  );

$creat_flags = (O_CREAT | O_EXCL | O_WRONLY | O_EXLOCK );

sysopen(SOMEHANDLE, $somepath, $creat_flags, 0666)
    || die "$0: couldn't sysopen $somepath with flags $creat_flags: $!";
于 2011-06-17T16:06:03.353 に答える