我正在开发一个将数据写入文件的工具。
在某些时候,文件可能会被“锁定”,并且在其他句柄关闭之前不可写入。
我可以使用CreateFile
API 处于循环状态,直到文件可用于写入访问。
但我有两个问题使用CreateFile
循环中:
- 硬盘驱动器(缓存)始终在运行...?!
- 我需要打电话
CreateFile
再次获得具有不同标志的有效写入句柄...?!
所以我的问题是:
等待文件可写并立即获得有效句柄的最佳解决方案是什么?
是否有任何事件解决方案或任何东西,允许一次“排队/保留”句柄,以便与其他人不存在“不受控制”的竞争条件?
文件可以“锁定”有两个原因:
- 实际的文件锁这会阻止写入,并可能阻止读取文件。
- 在没有共享访问权限的情况下打开文件(意外或自愿)这甚至会阻止您打开手柄。如果你已经看到了
CreateFile
失败,这很可能是这种情况,而不是真正的锁。
There are conceptually[1] at least two ways of knowing that no other process has locked a file without busy waiting:
- 通过找出谁持有锁并等待进程或线程退出(或者,通过彻底杀死它们......)
- 通过自己锁定文件
谁持有锁?
找出锁的所有者是相当令人讨厌的,你可以通过完全无证 SystemLocksInformation
与未记录的类一起使用NtQuerySystemInformation
函数(后者“只是未记录”,但前者没有太多记录,以至于很难找到任何信息)。返回的结构体解释here http://j00ru.vexillium.org/?p=269,并且它包含一个所属线程 ID。
Luckily,持有一把锁就意味着持有一个把手。关闭文件句柄将解锁所有文件范围。这意味着:没有把手就没有锁。
换句话说,问题也可以表示为“谁持有文件的打开句柄?”。当然,并非所有持有文件句柄的进程都会锁定该文件,但是没有进程有句柄保证没有进程锁定该文件。
找出哪些进程打开了文件的代码要容易得多(使用重新启动管理器)并且是一应俱全 http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx在雷蒙德·陈的网站上。
现在您知道哪些进程和线程正在持有文件句柄和锁,请列出所有线程/进程句柄并使用WaitForMultipleObjects
在进程句柄列表上。当进程退出时,所有句柄都将关闭。
这也透明地处理了“锁定”的可能性,因为进程不共享访问。
自己锁定文件
您可以使用LockFileEx
,它异步运行。注意LockFileEx
需要一个已打开的有效句柄either读或写权限(获得写权限可能是不可能的,但读应该几乎总是有效——即使你实际上被阻止了reading通过独占锁,仍然可以创建一个句柄可以阅读如果没有锁)。
然后,您可以通过以下事件等待异步锁定完成:OVERLAPPED
结构,或在完成端口上,甚至还可以同时做其他有用的事情。一旦您锁定了文件,您就知道没有其他人锁定了它。
[1] The wording
"conceptually" suggests that I am pretty sure either method will work, but I have not tested them.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)