lockfileex 不会阻止 create_always 擦除文件
在一个进程中,我使用 GENERIC_READ | 调用了 createfile GENERIC_WRITE、FILE_SHARE_READ | FILE_SHARE_WRITE、OPEN_ALWAYS 和 FILE_ATTRIBUTE_NORMAL 作为参数。 然后我对整个文件调用 LockFileEx 。我获得了一个独占锁,并且锁定范围为 0 到 UINT_MAX。
之后,在另一个进程中,我调用::CreateFileW(path.c_str(), perms, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
它删除了文件的内容。当我的其他进程已锁定文件(独占)时,它不应该无法做到这一点吗?
我希望其他进程能够获取该文件的句柄(这就是我使用 file_share 标志的原因),但我假设他们根本无法更改该文件,而另一个进程锁定了它,所以我正在做类似
createfile 的 事情 lockfileex
并让它阻塞在 lockfileex 上,直到另一个文件释放锁。是我的问题还是微软的行为有误?
in one process, i called createfile with GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, and FILE_ATTRIBUTE_NORMAL as the params.
then i called LockFileEx on the whole file. i acquired an exclusive lock, and locked from range 0 to UINT_MAX.
after that, in another process, i called ::CreateFileW(path.c_str(), perms, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
and it erased the contents of the file. shouldn't it not be able to do that while my other prcoess has the file locked (exclusively)?
i want other processes to be able to get handles to the file (which is why i used the file_share flags), but i assumed they couldnt change the file at all while another process locked it, and so i was doing something like
createfile
lockfileex
and having it block on lockfileex until the other file releases the lock. is it just me or is msft's behavior here wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您尝试使用 CREATE_ALWAYS 打开文件时,Windows 是否应该遵守文件锁定是有争议的,但从您的注释来看,事实并非如此。防止其他进程写入您已打开的文件的最佳方法是不要在独占进程中指定 FILE_SHARE_WRITE。
但是,这不会为您提供无需轮询即可从文件锁实现中获得的等待行为。无法以独占访问权限打开文件,并让尝试打开该文件的任何其他文件等待,直到具有独占访问权限的进程放弃该访问权限。
如果您有权访问所有涉及的进程的源,那么您可以让尝试截断文件的进程首先在某个区域上调用 LockFileEx,然后在获取锁后调用 SetFileSize。
附带说明一下,如果进程打开文件并尝试写入 UINT_MAX + 1 处的位置(刚刚超过 4GB 点),则仅锁定从 0 字节到 UINT_MAX 的区域不会提供互斥。
It is debatable whether Windows should honor file locks when you attempt to open a file with CREATE_ALWAYS, but it appears from your notes that it does not. The best way to prevent other processes from writing to a file that you have open is not to specify FILE_SHARE_WRITE in your exclusive process.
However, this won't give you the waiting behavior that you would get from the file lock implementation without polling. There is no way to open a file with exclusive access and have any other files that are attempting to open it wait until the process with exclusive access relinquishes that access.
If you have access to the source of all of the processes involved, then you could just have the processes that are attempting to truncate the file first call LockFileEx on a region, and then call SetFileSize after acquiring the lock.
As a side note, only locking the region from 0 bytes to UINT_MAX won't provide mutual exclusion if, say, a process opens the file and attempts to write to the location at UINT_MAX + 1 (just past the 4GB point).