机会锁的类型

机会锁操作适用于四种类型的机会锁:级别 1、级别 2、批处理和筛选器。 独占机会锁 是级别 1、批处理锁和筛选器锁。 如果线程在文件上具有任何类型的独占锁,则它不能在同一个文件上具有级别 2 锁。

级别 1 机会锁

文件上的 1 级机会锁允许客户端在文件中提前读取,并在本地缓存文件中的预读和写入数据。 只要客户端具有对文件的唯一访问权限,提供级别 1 的机会锁就没有数据一致性的危险。

客户端可以在打开文件后请求级别 1 的机会锁。 如果没有其他客户端 (或同一客户端) 上没有其他线程打开文件,则服务器可能会授予机会锁。 然后,客户端可以本地缓存文件中的读取和写入数据。 如果另一个客户端已打开该文件,则服务器会拒绝机会性锁,并且客户端不执行本地缓存。 (服务器可能出于其他原因拒绝机会性锁,例如不支持机会锁。)

当服务器打开一个已经具有 1 级机会锁的文件时,服务器会先检查该文件的共享状态,然后再打破级别 1 的机会锁。 如果服务器在此检查后断开锁,则使用前锁的客户端刷新其写入缓存的时间是请求文件的客户端必须等待的时间。 此时间消耗意味着应避免对许多客户端打开的文件使用 1 级机会性锁。

但是,由于服务器在断开锁定之前会检查共享状态,因此在服务器因共享冲突而拒绝打开请求的情况下,服务器不会中断锁定。 例如,如果已打开文件,拒绝共享写入操作,并获取级别 1 锁,则服务器会拒绝另一个客户端在文件上检查锁定之前打开文件进行写入的请求。 在此实例中,机会锁不会中断。

有关级别 1 机会锁的工作原理的示例,请参阅级别 1 机会锁示例。 有关中断机会锁的详细信息,请参阅 中断机会锁

级别 2 机会锁

级别 2 机会锁会通知客户端一个文件有多个并发客户端,并且尚未修改该文件。 此锁允许客户端使用缓存或预读本地信息执行读取操作并获取文件属性,但客户端必须发送所有其他请求 (,例如) 写入操作到服务器。 如果预期其他应用程序随机写入文件或随机或按顺序读取文件时,应用程序应使用级别 2 机会锁。

级别 2 机会锁与筛选器机会性锁非常相似。 在大多数情况下,应用程序应使用级别 2 机会锁。 仅当不希望打开读取操作导致应用程序打开文件与接收锁定之间的时间跨度内发生共享模式冲突时,才使用筛选器锁。 有关详细信息,请参阅筛选机会锁和 服务器对锁定文件打开请求的响应

有关中断机会锁的详细信息,请参阅 中断机会锁

Batch 机会锁

批处理机会锁操作文件打开和关闭。 例如,在执行批处理文件时,批处理文件可能针对文件的每一行打开和关闭一次。 批处理机会锁在服务器上打开批处理文件并使其保持打开状态。 当命令处理器“打开”和“关闭”批处理文件时,网络重定向程序将截获打开和关闭命令。 服务器接收的所有都是 seek 和 read 命令。 如果客户端也提前读取,则服务器最多接收一次特定的读取请求。

打开已具有批处理机会锁的文件时,服务器会在断开锁定后检查文件的共享状态。 此检查使锁的持有者有机会完成刷新其缓存并关闭文件句柄。 在共享检查期间尝试的打开操作不会导致共享检查失败(如果锁持有人松开锁)。

有关批处理机会锁的工作原理的示例,请参阅 Batch 机会锁示例。 有关中断机会锁的详细信息,请参阅 中断机会锁

筛选机会锁

筛选器机会锁会锁定文件,以便无法打开该文件进行写入或删除访问。 所有客户端都必须能够共享该文件。 筛选器锁允许应用程序对文件数据执行非侵入性筛选操作, (例如编译器打开源代码或编录程序) 。

筛选器机会锁与级别 2 机会锁的不同之处在于,它允许在应用程序打开文件和接收锁定之间的时间跨度内进行读取的打开操作,而不会发生共享模式冲突。 当允许其他客户端读取访问权限非常重要时,筛选器机会锁是最佳锁。 在其他情况下,应用程序应使用级别 2 机会锁。 筛选器机会锁不同于批处理机会锁,因为它不允许网络重定向程序处理多个打开和关闭,就像批处理机会锁那样。

应用程序应通过三个步骤请求文件上的筛选器机会锁:

  1. 使用 CreateFile 函数打开文件句柄,其中 DesiredAccess 参数设置为零,表示没有访问权限, dwShareMode 参数设置为 FILE_SHARE_READ 标志以允许共享进行读取。 此时获取的句柄称为锁定句柄。
  2. 使用 FSCTL_REQUEST_FILTER_OPLOCK 控制代码请求对此句柄的锁定。
  3. 授予锁后,使用 CreateFile 再次打开文件,并将 DesiredAccess 设置为 GENERIC_READ 标志。 将 dwShareMode 设置为 FILE_SHARE_READ 标志以允许其他人在打开文件时读取文件, FILE_SHARE_DELETE 标志允许其他人在打开文件时标记文件以供删除,或者两者兼而有。 此时获取的句柄称为读取句柄。

使用读取句柄读取或写入文件的内容。

打开已具有筛选器机会锁的文件时,服务器会断开锁定,然后检查文件的共享状态。 此检查使持有前机会主义锁的客户端有机会放弃任何缓存的数据并确认中断。 在此共享检查期间尝试的打开操作不会导致共享检查失败(如果前锁持有者释放锁)。 文件系统会保留打开操作,直到锁的所有者同时关闭读取句柄,然后关闭锁定句柄。 完成此操作后,其他客户端的打开请求可以继续。

有关中断机会锁的详细信息,请参阅 中断机会锁