2013-06-27 2 views
8

シナリオ:私はネット経由でファイルを取得する必要がある多くのプロセスを実行しています。ファイルが既にダウンロードされている場合は、そのファイルをディスクにキャッシュします。別のプロセスがファイルをダウンロードしている場合は、ダウンロードが完了するまでブロックします。Linuxでロックファイルをアトミックに作成するにはどうすればよいですか?

私はこれを行う最も簡単な方法を見つけるためにしようとしてきました。作成するなど、このシステムは、残念ながら、(一見)無競合状態

と上記の目標を達成し、私は)(オープンを使用する方法についてのドキュメントを見つけることができませんでした

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 

:明白な方法はにありますLinuxでロックされているファイル。私はに作成ステップを分割した場合:

open w/ O_CREAT | O_EXCL 
flock 

競合状態が今作成してロック(作成者が行う前に、非作成プロセスがロックを取得)の間に存在します。

ファイルごとに外部ロックファイル(例:filename + '.lock)を使用することができましたが、これはファイル名を作成しようとする前に取得していますが、これは気が気になりません(そして、それは実際に

を作成し、Windowsが提供していますとして(それをロックアトミックにとにかくあります)!の.lockサフィックスを持っている)か、外部ロックファイルメソッドはかなり標準/必要なものでしょうか?

答えて

6

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

は基本的に、ここでのfcntlロックを使用し、ファイルの存在自体を使用しないでください。ファイルが既に存在する場合、O_CREATとO_EXCLを持つopen()は失敗し、他の誰かが最初にそこに着いたことを伝えます。

+0

私はアトミックにファイルが存在しない場合にのみ、ロックされたファイルを作成することができればレースが存在するだろうかどうかはわかりません。 (条件もアトミックです)。 O_CREAT |ファイルが存在しない場合、O_EXCLはアトミック作成です。私はちょうどロックでそれをしたいです。ファイルが存在することを検出するため、別のプロセスがダウンロードを開始できません。最後に、ダウンロードが完了するまでブロックする必要があるため、私は単独でオープンを使用することはできません。私のソリューションでは、私は(排他的な読み取り/書き込み)ロックに依存しています。 – UsAaR33

+2

あなたは正しく、ファイルを原子的に作成してロックすることで問題が解決されます。しかし、それはfcntlのロックが動作する方法ではありません、申し訳ありません。 fcntlロックを使用する場合は、プログラムによって同期処理が行われる前に、ロックしているファイルが存在する必要があります。あなたの擬似コードの中でif()の外に作成を移動する方法を探したり、ダウンロードファイルをミューテックスとして使用しない別の同期プロトコルを作成したりしてください。 –

+0

答えが得られたので、LinuxはWindowsスタイルのアトミックロックを開くことができません。私はlockfileメソッドに固執します。 – UsAaR33

0

は、なぜあなたはロックファイルユーティリティを使用していませんか?

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

... 
lockfile important.lock 
... 
access_"important"_to_your_hearts_content 
... 
rm -f important.lock 
... 
関連する問題