ひねりを加えたファイルのロック
他の回答が述べたように、最も簡単な方法は、データファイルと同じディレクトリにロックファイルを作成することです。
複数のPCを介して同じファイルにアクセスできるようにしたいので、私が考えることができる最善の解決策は、現在データファイルに書き込んでいるマシンの識別子を含めることです。
したがって、データファイルへの書き込み順序は次のようになります。
ロックファイルが存在するかどうかを確認します
ロックファイルがある場合は、その内容に私の識別子が含まれていることを確認して、私がそれを所有しているかどうかを確認します。
その場合は、データファイルに書き込んでから、ロックファイルを削除してください。
そうでない場合は、1秒または少しランダムな時間待ってから、サイクル全体を再試行してください。
ロックファイルがない場合は、自分の識別子を使用してファイルを作成し、競合状態を回避するためにサイクル全体を再試行します(ロックファイルが本当に私のものであることを再確認してください)。
識別子とともに、タイムスタンプをロックファイルに記録し、指定されたタイムアウト値よりも古いかどうかを確認します。
タイムスタンプが古すぎる場合は、ロックファイルが古くなっていると想定し、データファイルに書き込んでいるPCの1つがクラッシュしたか、接続が失われた可能性があるため、ロックファイルを削除します。
別の解決策
データファイルの形式を制御している場合は、ファイルの先頭にある構造を予約して、ロックされているかどうかを記録することができます。
この目的のためにバイトを予約するだけの場合、たとえば、00
データファイルがロックされておらず、他の値が現在書き込み中のマシンの識別子を表していると想定できます。
NFSの問題
OK、いくつか追加します。JiriKloudaは、NFSがクライアント側のキャッシュを使用しているため、実際のロックファイルが未確定の状態になることを正しく指摘しているためです。
この問題を解決するいくつかの方法:
noac
またはsync
オプションを使用してNFSディレクトリをマウントします。これは簡単ですが、クライアントとサーバー間のデータの一貫性を完全に保証するものではありません。そのため、問題が発生する可能性がありますが、場合によっては問題ない可能性があります。
O_DIRECT
、、O_SYNC
または属性を使用して、ロックファイルまたはデータファイルを開きO_DSYNC
ます。これにより、キャッシュが完全に無効になります。
これによりパフォーマンスは低下しますが、一貫性が確保されます。
を使用してデータファイルをロックできる場合がありますflock()
が、その実装は不十分であり、特定のOSが実際にNFSロックサービスを使用しているかどうかを確認する必要があります。それ以外の場合は何もしません。
データファイルがロックされている場合、書き込みのためにデータファイルを開いている別のクライアントは失敗します。
そうそう、SMB共有では機能しないように思われるので、それを忘れるのがおそらく最善です。
NFSを使用せず、代わりにSambaを使用してください。このテーマに関する優れた記事があり、NFSが使用シナリオに対する最良の答えではない理由があります。
この記事には、ファイルをロックするためのさまざまな方法もあります。
Jiriのソリューションも良いものです。
基本的に、物事を単純にしたい場合は、複数のマシン間で共有される頻繁に更新されるファイルにNFSを使用しないでください。
何か違います
小さなデータベースサーバーを使用してデータを保存し、NFS / SMBロックの問題を完全に回避するか、現在の複数のデータファイルシステムを維持し、結果を連結するための小さなユーティリティを作成します。
それでも、問題に対する最も安全で簡単な解決策になる可能性があります。