日和見ロックの種類

日和見ロック操作は、レベル 1、レベル 2、バッチ、フィルターの 4 種類の日和見ロックで動作します。 排他日和見ロック は、レベル 1、バッチ、およびフィルター ロックです。 スレッドがファイルに対して何らかの種類の排他ロックを持っている場合、同じファイルに対してレベル 2 のロックを持つことはできません。

レベル 1 の日和見ロック

ファイルに対するレベル 1 の日和見ロックを使用すると、クライアントはファイルを先読みし、先読みとファイルからのデータの書き込みの両方をローカルにキャッシュできます。 クライアントがファイルへの唯一のアクセス権を持っている限り、レベル 1 の日和見ロックを提供する際にデータの一貫性を危険にさらす危険はありません。

クライアントは、ファイルを開いた後、レベル 1 の日和見ロックを要求できます。 他のクライアント (または同じクライアント上の他のスレッド) がファイルを開いていなくても、サーバーは日和見ロックを許可できます。 その後、クライアントはファイルからの読み取りと書き込みのデータをローカルにキャッシュできます。 別のクライアントがファイルを開いた場合、サーバーは日和見ロックを拒否し、クライアントはローカル キャッシュを実行しません。 (サーバーは、日和見ロックをサポートしていないなど、他の理由で日和見ロックを拒否する場合もあります)。

サーバーが既にレベル 1 の日和見ロックを持つファイルを開くと、サーバーはファイルの共有状態を調べてから、レベル 1 の日和見ロックを解除します。 この検査の後にサーバーがロックを解除した場合、以前のロックを持つクライアントが書き込みキャッシュのフラッシュに費やす時間は、ファイルを要求するクライアントが待機する必要がある時間です。 今回の支出は、多くのクライアントが開いているファイルでは、レベル 1 の日和見ロックを回避する必要があることを意味します。

ただし、サーバーはロックを解除する前に共有状態をチェックするため、共有の競合によりサーバーがオープン要求を拒否する場合、サーバーはロックを中断しません。 たとえば、ファイルを開き、書き込み操作の共有を拒否し、レベル 1 のロックを取得した場合、サーバーは、ファイルのロックを調べる前に、書き込み用にファイルを開く別のクライアントの要求を拒否します。 このインスタンスでは、日和見ロックは壊れていません。

レベル 1 の日和見ロックのしくみの例については、「レベル 1 の日和見ロックの例」を参照してください。 日和見ロックの解除の詳細については、「日和見ロック の中断」を参照してください。

レベル 2 の日和見ロック

レベル 2 の日和見ロックは、ファイルの同時クライアントが複数あり、まだ変更されていないことをクライアントに通知します。 このロックにより、クライアントはキャッシュされたローカル情報または先読みローカル情報を使用して読み取り操作を実行し、ファイル属性を取得できますが、クライアントは他のすべての要求 (書き込み操作など) をサーバーに送信する必要があります。 アプリケーションでは、他のアプリケーションがファイルにランダムに書き込むか、ファイルをランダムまたは順番に読み取る必要がある場合は、レベル 2 の日和見ロックを使用する必要があります。

レベル 2 の日和見ロックは、フィルターの日和見ロックとよく似ています。 ほとんどの状況では、アプリケーションでレベル 2 の日和見ロックを使用する必要があります。 読み取り用に開いている操作で、アプリケーションがファイルを開いてロックを受信するまでの間に共有モード違反を引き起こさない場合にのみ、フィルター ロックを使用します。 詳細については、「フィルター日和見ロック」および「 ロックされたファイルのオープン要求へのサーバー応答」を参照してください。

日和見ロックの解除の詳細については、「日和見ロック の中断」を参照してください。

Batch Opportunistic Locks

バッチの日和見ロックは、ファイルの開閉を操作します。 たとえば、バッチ ファイルの実行では、ファイルの各行に対してバッチ ファイルを 1 回開いて閉じることができます。 バッチの日和見ロックによって、サーバー上のバッチ ファイルが開き、開いたままになります。 コマンド プロセッサがバッチ ファイルを "開く" と "閉じる" と、ネットワーク リダイレクターは開いているコマンドと閉じるコマンドをインターセプトします。 すべてのサーバーが受信するシークコマンドと読み取りコマンドです。 クライアントも先読みしている場合、サーバーは特定の読み取り要求を最大 1 回受信します。

バッチ日和見ロックが既にあるファイルを開くと、サーバーはロックを解除した後にファイルの共有状態を確認します。 このチェックは、ロックの所有者にキャッシュのフラッシュを完了し、ファイル ハンドルを閉じる機会を与えます。 共有チェック中にオープン操作が試行されても、ロック所有者がロックを解放しても、共有チェックは失敗しません。

バッチ日和見ロックのしくみの例については、「Batch Opportunistic Lock Example」を参照してください。 日和見ロックの解除の詳細については、「日和見ロック の中断」を参照してください。

日和見ロックのフィルター処理

フィルターの日和見ロックは、書き込みアクセスまたは削除アクセス用にファイルを開くことができないようにファイルをロックします。 すべてのクライアントがファイルを共有できる必要があります。 フィルター ロックを使用すると、アプリケーションはファイル データ (ソース コードやカタログプログラムを開くコンパイラなど) に対して非統合フィルター処理操作を実行できます。

フィルターの日和見ロックは、レベル 2 の日和見ロックとは異なり、アプリケーションがファイルを開いてロックを受信するまでの間に、共有モード違反なしで読み取り操作を開くことができます。 フィルターの日和見ロックは、他のクライアントに読み取りアクセスを許可することが重要な場合に使用する最適なロックです。 それ以外の場合は、アプリケーションでレベル 2 の日和見ロックを使用する必要があります。 フィルターの日和見ロックは、バッチの日和見ロックと異なり、バッチの日和見ロックの場合と同様に、ネットワーク リダイレクターによって複数の開始と終了を処理できないという点で異なります。

アプリケーションでは、次の 3 つの手順でファイルに対してフィルターの日和見ロックを要求する必要があります。

  1. CreateFile 関数を使用して、DesiredAccess パラメーターを 0 に設定してファイルへのハンドルを開き、アクセスがないことを示し、dwShareMode パラメーターを FILE_SHARE_READ フラグに設定して読み取りを共有できるようにします。 この時点で取得されたハンドルは、ロック ハンドルと呼ばれます。
  2. FSCTL_REQUEST_FILTER_OPLOCKコントロール コードを使用して、このハンドルのロック 要求します。
  3. ロックが許可されたら、 CreateFile を 使用して、 DesiredAccessGENERIC_READ フラグに設定してファイルをもう一度開きます。 dwShareModeFILE_SHARE_READ フラグに設定すると、開いている間に他のユーザーがファイルを読み取れるようにしたり、他のユーザーがファイルを開いている間に削除のマークを付けたりできるFILE_SHARE_DELETE フラグ、またはその両方が許可されます。 この時点で取得されたハンドルは、読み取りハンドルと呼ばれます。

読み取りハンドルを使用して、ファイルの内容の読み取りまたは書き込みを行います。

フィルターの日和見ロックが既にあるファイルを開くと、サーバーはロックを解除し、ファイルの共有状態を確認します。 このチェックは、以前の日和見ロックを保持したクライアントに、キャッシュされたデータを破棄して中断を確認する機会を与えます。 この共有チェック中にオープン操作を試行しても、前者のロック・ホルダーがロックを解放しても、共有チェックは失敗しません。 ファイル システムは、ロックの所有者が読み取りハンドルとロック ハンドルの両方を閉じるまで、開いている操作を保持します。 これが完了すると、他のクライアントのオープン要求を続行できます。

日和見ロックの解除の詳細については、「日和見ロック の中断」を参照してください。