13

シナリオ: ネット経由でファイルをフェッチする必要があるプロセスを多数実行しています。ファイルが既にダウンロードされている場合は、ディスクにキャッシュします。別のプロセスがファイルをダウンロードしている場合は、ダウンロードが完了するまでブロックします。

これを行う最も簡単な方法を見つけようとしています。明らかな方法は次のとおりです。

create file w/ an exclusive lock active on it only if it doesn't exist (O_CREAT | O_EXCL)
if file exists already:
   open file and acquire exclusive lock
else:
   download to newly created file
release lock

このシステムは、(一見) 競合状態なしで上記の目標を達成します。

残念ながら、open() などを使用して Linux でロックされたファイルを作成する方法に関するドキュメントは見つかりませんでした。作成ステップを次のように分割すると:

open w/ O_CREAT | O_EXCL
flock

作成とロックの間に競合状態が存在するようになりました (非作成プロセスは、作成者がロックを取得する前にロックを取得します)。

ファイルごとに外部ロックファイル (例: filename + '.lock) を使用できることに気付きました。これは、ファイル名を作成する前に取得しますが、これは.. 洗練されていないと感じます (そして、実際に.lock サフィックス!)

とにかくアトミックに作成してロックする方法はありますか(Windowsが提供するように)、または外部ロックファイルメソッドは標準/必須のものですか?

4

3 に答える 3

9

レースはとにかく存在します。ファイルが存在するかどうかわからない場合は、ロックする前にその存在をテストする必要があります。しかし、ファイルがミューテックスである場合、おそらくそれを行うことはできず、「ファイルが既に存在する場合」(false) と「新しく作成されたファイルにダウンロードする」の間のスペースには制約がありません。別のプロセスが来て、ファイルを作成し、ダウンロードが始まる前にダウンロードを開始する可能性があり、それを破壊することになります.

ここでは基本的に fcntl ロックを使用せず、ファイル自体の存在を使用します。 open()O_CREAT および O_EXCL を使用すると、ファイルが既に存在する場合は失敗し、他の誰かが最初にそこに到達したことがわかります。

于 2013-06-27T20:45:53.327 に答える
0

lockfile ユーティリティを使用しないのはなぜですか?

ファイル「重要」へのアクセスがシリアル化されていることを確認したいとします。つまり、複数のプログラムまたはシェル スクリプトにアクセスを許可しないようにします。簡単にするために、それがシェルスクリプトであるとしましょう。この場合、次のように解決できます。

...
lockfile important.lock
...
access_"important"_to_your_hearts_content
...
rm -f important.lock
...
于 2016-09-02T18:29:52.673 に答える