これが重要です。C++で記述され、OSが異なる2台のマシン(1台のLinuxと1台のWindows)で実行されている2つのアプリケーションがあります。このプロセスの1つは、NAS(Network Attached Storage)上のXMLファイルの更新を担当し、もう1つはこのファイルを読み取ります。
変更中のファイルの読み取りを回避するために、これら2つのプロセスを同期することは可能ですか?
これが重要です。C++で記述され、OSが異なる2台のマシン(1台のLinuxと1台のWindows)で実行されている2つのアプリケーションがあります。このプロセスの1つは、NAS(Network Attached Storage)上のXMLファイルの更新を担当し、もう1つはこのファイルを読み取ります。
変更中のファイルの読み取りを回避するために、これら2つのプロセスを同期することは可能ですか?
書き込みを行う前に作成されたロックファイルをサーバー上に作成し、待機してから書き込みを完了し、完了時に削除することができます。ファイルを読み取る前に、読み取りプロセスにトークンをチェックさせます。
編集:コメントに対処するために、ダブルチェックのロックタイプパターンを実装できます。リーダーとライターの両方にロックファイルを用意し、作業を行う前に次のように再確認してください。
リーダー:書き込みロックファイルを確認し、読み取りロックファイルを作成し、書き込みロックファイルを確認します。存在する場合は、読み取りファイルを削除して中止します。
ライター:読み取りロックファイルを確認し、書き込みロックファイルを作成し、読み取りロックファイルを確認します。存在する場合は、書き込みロックファイルを削除して中止します。
これにより、プロセスが互いに踏みにじられるのを防ぐことができますが、両方のプロセスを同時にチェックし、作成してから再チェックする可能性があるという競合状態が発生する可能性があります。ただし、これにより、データが不整合な状態で読み取られることはありませんが、両方の読み取りが発生します。指定した遅延で中止するプロセスを作成します
回答ありがとうございます。
ついに、OSのロックコマンドを使用するのではなく(NASヘッドのOSに正しく伝播するかどうかわからなかったため)、ロックファイルの代わりにロックディレクトリを作成することで、問題を解決することができました。ディレクトリの作成は不可分操作であり、フォルダがすでに存在する場合はエラー値を返します。したがって、ロックを取得する前にロックの存在を確認する必要はなく、両方の操作が1つのステップで実行されます。
OK、アクセスを制御するために何らかの形のロックメカニズムが必要です。
ほとんどの*nixファイルシステムはこれを提供します。Windowsファイルシステムでも利用できると思いますが(このメカニズムはperlで使用されているため)、別の名前が付けられている可能性があります。
flock()を見てください。
これはファイルロックメカニズムです。これはアドバイザリロックであるため、実際にファイルをロックして使用を妨げることはありませんが、ファイルにマークを付けるためのメカニズムを提供します。両方のアプリケーションがこのメカニズムを使用している場合は、ファイルへのアクセスを制御できます。
flock()は、共有ロック(またはREADロック)と排他ロック(またはWRITEロック)の両方を提供します。flockは、ファイルがユーザーによってロック解除されるまで(非ビジーな方法で)スレッドをブロックします(待機中に他のことを実行できるように、非ブロックチェックも提供します)。
マニュアルページのセクション2で群れをチェックしてください。
int flock(int fd, int operation);
Flock() applies or removes an advisory lock on the file associated with the file
descriptor fd. A lock is applied by specifying an operation parameter that is
one of LOCK_SH or LOCK_EX with the optional addition of LOCK_NB. To unlock an
existing lock operation should be LOCK_UN.