日和見ロックの種類
日和見ロック操作は、レベル 1、レベル 2、バッチ、フィルターの 4 種類の日和見ロックで動作します。 排他的日和見ロック は、レベル 1、バッチ、およびフィルター ロックです。 スレッドがファイルに対して何らかの排他的ロックを持っている場合は、同じファイルに対してレベル 2 のロックを設定することもできません。
レベル 1 の日和見ロック
ファイルに対するレベル 1 の日和見ロックを使用すると、クライアントはファイルを先読みし、先読みとファイルからのデータの書き込みの両方をローカルにキャッシュできます。 クライアントがファイルへの唯一のアクセス権を持っている限り、レベル 1 の日和見ロックを提供する場合、データの一貫性に危険はありません。
クライアントは、ファイルを開いた後、レベル 1 の日和見ロックを要求できます。 他のクライアント (または同じクライアント上の他のスレッド) がファイルを開いていなくても、サーバーは日和見ロックを許可できます。 その後、クライアントはファイルの読み取りと書き込みのデータをローカルにキャッシュできます。 別のクライアントがファイルを開いた場合、サーバーは日和見ロックを拒否し、クライアントはローカル キャッシュを実行しません。 (サーバーは、日和見ロックをサポートしていないなど、他の理由で日和見ロックを拒否する場合もあります)。
サーバーが既にレベル 1 の日和見ロックを持つファイルを開くと、サーバーはファイルの共有状態を調べてから、レベル 1 の日和見ロックを解除します。 この検査後にサーバーがロックを解除した場合、前者のロックを持つクライアントが書き込みキャッシュのフラッシュに費やす時間は、ファイルを要求するクライアントが待機する必要があります。 今回の支出は、多くのクライアントが開いているファイルでは、レベル 1 の日和見ロックを回避する必要があることを意味します。
ただし、サーバーはロックを解除する前に共有状態をチェックするため、共有の競合によってサーバーが開いている要求を拒否する場合、サーバーはロックを解除しません。 たとえば、ファイルを開き、書き込み操作の共有を拒否し、レベル 1 のロックを取得した場合、サーバーはファイルのロックを調べる前に、書き込みのためにファイルを開く別のクライアントの要求を拒否します。 この場合、日和見ロックは解除されません。
レベル 1 の日和見ロックのしくみの例については、「レベル 1 の日和見ロックの例」を参照してください。 日和見ロックの解除の詳細については、「日和見ロック の解除」を参照してください。
レベル 2 の日和見ロック
レベル 2 の日和見ロックは、ファイルの同時実行クライアントが複数あり、まだ変更されていないことをクライアントに通知します。 このロックにより、クライアントはキャッシュされたローカル情報または先読みローカル情報を使用して読み取り操作を実行し、ファイル属性を取得できますが、クライアントは他のすべての要求 (書き込み操作など) をサーバーに送信する必要があります。 アプリケーションでは、他のアプリケーションがファイルにランダムに書き込むか、ファイルをランダムまたは順番に読み取る必要がある場合は、レベル 2 の日和見ロックを使用する必要があります。
レベル 2 の日和見ロックは、フィルターの日和見ロックとよく似ています。 ほとんどの場合、アプリケーションはレベル 2 の日和見ロックを使用する必要があります。 フィルター ロックは、アプリケーションがファイルを開いてロックを受け取るまでの間に共有モード違反を引き起こす読み取り操作を開かないようにする場合にのみ使用します。 詳細については、「ロック されたファイルで開いている要求に対する日和見ロックとサーバー応答のフィルター処理」を参照してください。
日和見ロックの解除の詳細については、「日和見ロック の解除」を参照してください。
バッチの日和見ロック
バッチの日和見ロックは、ファイルの開閉を操作します。 たとえば、バッチ ファイルの実行では、ファイルの行ごとにバッチ ファイルを 1 回開いたり閉じたりすることができます。 バッチの日和見ロックは、サーバー上のバッチ ファイルを開き、開いたままにします。 コマンド プロセッサがバッチ ファイルを "開く" と "閉じる" と、ネットワーク リダイレクターは開いているコマンドと閉じるコマンドをインターセプトします。 受信するサーバーはすべて、シーク コマンドと読み取りコマンドです。 クライアントも先読みしている場合、サーバーは特定の読み取り要求を最大 1 回受信します。
バッチの日和見ロックが既にあるファイルを開くと、サーバーはロックを解除した後にファイルの共有状態を確認します。 このチェックにより、ロックの所有者はキャッシュのフラッシュを完了し、ファイル ハンドルを閉じる機会が得られます。 共有チェック中にオープン操作を試行しても、ロック所有者がロックを解放しても、共有チェックは失敗しません。
バッチの日和見ロックのしくみの例については、「バッチ日和見ロックの例」を参照してください。 日和見ロックの解除の詳細については、「日和見ロック の解除」を参照してください。
日和見ロックのフィルター処理
フィルターの日和見ロックは、書き込みアクセスまたは削除アクセスのためにファイルを開くことができないように、ファイルをロックします。 すべてのクライアントがファイルを共有できる必要があります。 フィルター ロックを使用すると、アプリケーションはファイル データ (たとえば、ソース コードやカタログ プログラムを開くコンパイラ) に対して非インラスシブ フィルター処理を実行できます。
フィルターの日和見ロックは、アプリケーションがファイルを開いてロックを受け取るまでの間に、共有モード違反なしで読み取りを行うオープン操作を可能にする点で、レベル 2 の日和見ロックとは異なります。 フィルターの日和見ロックは、他のクライアントにアクセスの読み取りを許可することが重要な場合に使用する最適なロックです。 それ以外の場合は、アプリケーションでレベル 2 の日和見ロックを使用する必要があります。 フィルターの日和見ロックは、バッチの日和見ロックと異なり、バッチの日和見ロックの場合と同様に、ネットワーク リダイレクターによって複数の開始と終了を処理することはできません。
アプリケーションは、次の 3 つの手順でファイルに対してフィルターの日和見ロックを要求する必要があります。
- CreateFile 関数を使用して、DesiredAccess パラメーターが 0 に設定されたファイルへのハンドルを開き、アクセス権がないことを示し、dwShareMode パラメーターを FILE_SHARE_READ フラグに設定して読み取りを共有できるようにします。 この時点で取得されたハンドルは、ロック ハンドルと呼ばれます。
- FSCTL_REQUEST_FILTER_OPLOCK コントロール コードを使用して、このハンドルのロック を 要求します。
- ロックが付与されたら、 CreateFile を 使用して、 DesiredAccess を GENERIC_READ フラグに設定してファイルを再度開きます。 dwShareMode を FILE_SHARE_READ フラグに設定して、ファイルを開いている間に他のユーザーがファイルを読み取れるようにします。他のユーザーがファイルを開いている間に削除のマークを付けるFILE_SHARE_DELETE フラグ、またはその両方を許可します。 この時点で取得されたハンドルは、読み取りハンドルと呼ばれます。
読み取りハンドルを使用して、ファイルの内容の読み取りまたは書き込みを行います。
フィルターの日和見ロックが既にあるファイルを開くと、サーバーはロックを解除し、ファイルの共有状態を確認します。 このチェックにより、以前の日和見ロックを保持したクライアントは、キャッシュされたデータを破棄し、中断を確認する機会が得られます。 この共有チェック中にオープン操作を試行しても、前者のロック所有者がロックを解放しても、共有チェックは失敗しません。 ファイル システムは、ロックの所有者が読み取りハンドルとロック ハンドルの両方を閉じるまで、開いている操作を保留にします。 これが完了すると、もう一方のクライアントの開いている要求を続行できます。
日和見ロックの解除の詳細については、「日和見ロック の解除」を参照してください。