文件解锁和删除为单一操作
请注意,这与文件读/写锁定和取消链接不重复。 (区别在于平台。锁定和删除等文件操作具有完全不同的语义,因此结果会不同)。
我有以下问题。我想创建一个基于文件系统的会话存储,其中每个会话数据都存储在以会话 ID 命名的简单文件中。
我想要以下 API:write(sid,data,timeout)
、read(sid,data,timeout)
、remove(sid)
其中 sid== 文件名,另外我想要某种可以删除所有超时会话的 GC。
如果您使用单个进程,这是相当简单的任务,但在使用多个进程甚至共享文件夹时绝对不是微不足道的。
我想到的最简单的解决方案是:
write/read:
hanlde=CreateFile
LockFile(handle)
read/write data
UnlockFile(handle)
CloseHanlde(handle)
GC (for each file in directory)
hanlde=CreateFile
LockFile(handle)
check if timeout occured
DeleteFile
UnlockFile(handle)
CloseHanlde(handle)
但是我不能在打开的锁定文件上调用 DeleteFile
(不像在 Unix 中,文件锁定是 不是强制性的,并且允许对打开的文件取消链接。
但是,如果我将 DeleteFile
放在锁定循环之外,可能会发生不良情况
GC - CreateFile/LockFile/Unlock/CloseHandle,
write - oCreateFile/LockFile/WriteUpdatedData/Unlock/CloseHandle
GC - DeleteFile
有人知道如何解决此类问题吗?有什么技巧可以让 结合文件锁定和文件删除或对文件进行原子操作(Win32)?
注释:
- 我不想使用数据库,
- 我正在寻找适用于 NT 5.01 及更高版本的 Win32 API 的解决方案,
谢谢。
Please note this is not duplicate of File r/w locking and unlink. (The difference - platform. Operations of files like locking and deletion have totally different semantics, thus the sultion would be different).
I have following problem. I want to create a file system based session storage where each session data is stored in simple file named with session ids.
I want following API: write(sid,data,timeout)
, read(sid,data,timeout)
, remove(sid)
where sid==file name, Also I want to have some kind of GC that may remove all timed-out sessions.
Quite simple task if you work with single process but absolutly not trivial when working with multiple processes or even over shared folders.
The simplest solution I thought about was:
write/read:
hanlde=CreateFile
LockFile(handle)
read/write data
UnlockFile(handle)
CloseHanlde(handle)
GC (for each file in directory)
hanlde=CreateFile
LockFile(handle)
check if timeout occured
DeleteFile
UnlockFile(handle)
CloseHanlde(handle)
But AFIAK I can't call DeleteFile
on opended locked file (unlike in Unix where file locking is
not mandatory and unlink is allowed for opened files.
But if I put DeleteFile
outside of Locking loop bad scenario may happen
GC - CreateFile/LockFile/Unlock/CloseHandle,
write - oCreateFile/LockFile/WriteUpdatedData/Unlock/CloseHandle
GC - DeleteFile
Does anybody have an idea how such issue may be solved? Are there any tricks that allow
combine file locking and file removal or make operation on file atomic (Win32)?
Notes:
- I don't want to use Database,
- I look for a solution for Win32 API for NT 5.01 and above
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我真的不明白这应该如何运作。但是,删除由另一个进程打开的文件是可能的。创建文件的进程必须使用 CreateFile() 的 dwShareMode 参数的 FILE_SHARE_DELETE 标志。随后的DeleteFile() 调用将会成功。在关闭文件的最后一个句柄之前,该文件实际上不会从文件系统中删除。
I don't really understand how this is supposed to work. However, deleting a file that's opened by another process is possible. The process that creates the file has to use the FILE_SHARE_DELETE flag for the dwShareMode argument of CreateFile(). A subsequent DeleteFile() call will succeed. The file doesn't actually get removed from the file system until the last handle on it is closed.
当前记录中的数据允许 GC 确定记录是否超时。使用“TooLateWeAlreadyTimedItOut”标志扩展该内务信息怎么样?
换句话说,我们正在使用一种乐观锁定方法。这确实需要 Writer 具有一些额外的复杂性,但现在您不再依赖于任何特定于操作系统的问题。
我不清楚这种情况下会发生什么:
无论您为此情况计划了什么,也可以在“TooLate”情况下使用
编辑添加:
您已经说过这个序列的发生是有效的:
作者可以对待“tooLate” " 标记与本例相同。它只是创建一个具有不同名称的新文件,使用版本号作为其名称的尾随部分。第一次打开会话文件需要进行目录搜索,但随后您可以在会话中存储最新的名称。
这确实假设给定会话只能有一个 Writer 线程,或者我们可以在创建文件的两个 Writer 线程之间进行调解,但这对于您的简单 GC/Writer 案例来说必须如此。
You currently have data in the record that allows the GC to determine if the record is timed out. How about extending that housekeeping info with a "TooLateWeAlreadyTimedItOut" flag.
In other words we're using a kind of optimistic locking approach. This does require some additional complexity in the Writer, but now you're not dependent upon any OS-specifc wrinkles.
I'm not clear what happens in the case:
Whatever you have planned for this case can also be used in the "TooLate" case
Edited to add:
You have said that it's valid for this sequence to occur:
The writer can treat "tooLate" flag as a identical to this case. It just creates a new file, with a different name, use a version number as a trailing part of it's name. Opening a session file the first time requires a directory search, but then you can stash the latest name in the session.
This does assume that there can only be one Writer thread for a given session, or that we can mediate between two Writer threads creating the file, but that must be true for your simple GC/Writer case to work.
对于 Windows,您可以使用 FILE_FLAG_DELETE_ON_CLOSE 选项CreateFile - 当您关闭句柄时,这将导致文件被删除。但我不确定这是否满足您的语义(因为我不相信您可以清除关闭时删除属性。
这是另一个想法。在删除文件之前重命名该文件怎么样?您根本无法关闭该文件决定删除文件后写入的窗口,但是如果在删除文件之前重命名该文件,那么当写入进入时,它会发现会话文件不存在并重新创建它
。请记住,您根本无法关闭有问题的窗口,恕我直言,有两种解决方案:
,如果您过早地删除该文件,会出现什么问题?毕竟您的系统必须处理不存在的文件...
For Windows, you can use the FILE_FLAG_DELETE_ON_CLOSE option to CreateFile - that will cause the file to be deleted when you close the handle. But I'm not sure that this satisfies your semantics (because I don't believe you can clear the delete-on-close attribute.
Here's another thought. What about renaming the file before you delete it? You simply can't close the window where the write comes in after you decided to delete the file but what if you rename the file before deleting it? Then when the write comes in it'll see that the session file doesn't exist and recreate it.
The key thing to keep in mind is that you simply can't close the window in question. IMHO there are two solutions:
What is the downside of having a TooLate flag? In other words, what goes wrong if you delete the file prematurely? After all your system has to deal with the file not being present...