题
请注意,这不是重复的 文件读/写锁定和取消链接. 。(区别 - 平台。文件的操作(如锁定和删除)具有完全不同的语义,因此结果会不同)。
我有以下问题。我想创建一个基于文件系统的会话存储,其中每个会话数据都存储在以会话 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不同,该文件不强制性锁定,并且打开文件允许UNINK。
但如果我把 DeleteFile
在锁定循环之外可能会发生不良情况
GC - CreateFile/LockFile/Unlock/CloseHandle,
write - oCreateFile/LockFile/WriteUpdatedData/Unlock/CloseHandle
GC - DeleteFile
有人知道如何解决这样的问题吗?有什么技巧可以允许 将文件锁定和文件删除结合起来,还是在文件原子 (Win32) 上进行操作?
笔记:
- 我不想使用数据库,
- 我正在寻找适用于 NT 5.01 及更高版本的 Win32 API 的解决方案
谢谢。
解决方案
我真的不明白这应该如何运作。但是,删除由另一个进程打开的文件是可能的。创建文件的进程必须使用 CreateFile() 的 dwShareMode 参数的 FILE_SHARE_DELETE 标志。随后的DeleteFile() 调用将会成功。在关闭文件的最后一个句柄之前,该文件实际上不会从文件系统中删除。
其他提示
当前记录中的数据允许 GC 确定记录是否超时。使用“TooLateWeAlreadyTimedItOut”标志扩展该内务信息怎么样?
GC sets TooLateWeAlreadyTimedItOut = true
Release lock
<== writer comes in here, sees the "TooLate" flag and so does not write
GC deletes
换句话说,我们正在使用一种乐观锁定方法。这确实需要 Writer 具有一些额外的复杂性,但现在您不再依赖于任何特定于操作系统的问题。
我不清楚此案发生了什么:
GC checks timeout
GC deletes
Writer attempts write, and finds no file ...
您为此案例计划的任何内容也可以用于“TooLate”案例
编辑添加:
您已经说过这个序列的发生是有效的:
GC Deletes
(Very slightly later) Writer attempts a write, sees no file, creates a new one
作者可以将“tooLate”标志视为与本例相同。它只是创建一个 新的 文件,具有不同的名称,使用版本号作为其名称的尾部部分。第一次打开会话文件需要进行目录搜索,但随后您可以在会话中存储最新的名称。
这确实假设给定会话只能有一个 Writer 线程,或者我们可以在创建文件的两个 Writer 线程之间进行调解,但这对于您的简单 GC/Writer 案例来说必须是正确的。
对于 Windows,您可以使用 FILE_FLAG_DELETE_ON_CLOSE CreateFile 的选项 - 这将导致在关闭句柄时删除文件。但我不确定这是否满足您的语义(因为我不相信您可以清除关闭时删除属性。
这是另一个想法。在删除文件之前重命名该文件怎么样?在决定删除文件后,您根本无法关闭写入的窗口,但是如果您在删除文件之前重命名该文件怎么办?然后,当写入进来时,它会发现会话文件不存在并重新创建它。
要记住的关键是您根本无法关闭有问题的窗口。恕我直言,有两种解决方案:
- 添加像 djna 提到的标志或
- 要求获取名为互斥体的每个会话,这会产生序列化会话写入的不幸副作用。
使用 TooLate 标志有什么缺点?换句话说,如果过早删除文件会出现什么问题?毕竟您的系统必须处理不存在的文件......