2011-06-17 8 views
4

作成時に読み取りに対してロックされたファイルを作成して、このファイルを探している他のプロセスが完全に書き込まれる前に読み取りを開始しないようにする必要があります。作成時にロックされているファイルをPerlで作成する方法はありますか?

私は作成することができ、を次にロックすることがわかっていますが、これは私が競争状態に開放されることを心配しています。

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

+0

http://perl.plover.com/yak/flock/samples/slide011.html – daxim

+0

@daximそれが唯一の_advisory_ロックだ - それは開口部からセマフォのセマンティクスに従わないのプロセスを防ぐことはできません。ファイル。 – Alnitak

答えて

7

あり>>>との競合状態であるが、それは、+<を使用して回避することができます。

# > 
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はアトミックアクションであるため、ファイルは完全にリーダが監視するディレクトリに表示されます。これにはライターの協力が必要ですが、最善の解決策があります。

+0

@Dancrumb、私は私の答えに追加しました。 – ikegami

+0

競合状態は、読み取りがWriterのオープン(したがって作成)とファイルのロックとの間でファイルを開くときに発生します。 – Dancrumb

+0

@Dancrumb、もちろん!しかし、私が記述した戦略はそれに対処しています。私はそれに応じて私の投稿を調整しました。 – ikegami

9

ファイルを作成する前に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 

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

[*] root processeを除く。

(FWIW、半書かれたファイルを読み込むますEOF状態で結果。)

+1

ある意味では、それはUNIX上で提供される 'flock'よりも優れたロックです。単なる助言ではありません。 – ikegami

+0

ありがとう@Alnitak。私は一般的にIO :: Fileを使用し、その呼び出しでアクセス権を設定することができます...多くの義務 – Dancrumb

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: $!"; 
関連する問題