0

我有以下问题。我想创建一个基于文件系统的会话存储,其中每个会话数据都存储在以会话 ID 命名的简单文件中。

我想要以下 API: write(sid,data,timeout), read(sid,data,timeout),remove(sid) 其中 sid==file name, 另外我想要某种可以删除所有超时会话的 GC。

如果您使用单个进程,则任务非常简单,但在使用多个进程甚至通过 NFS 时绝对不是微不足道的。

我想到的最简单的解决方案是:

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

GC:
   fd=open(file_name,O_RDWR);
   fcntl_lock_file(fd)
   if(timed_out)
      unlink(file_name)
   fcntl_unlock_file(fd)
   close(fd)

文件取消链接适用于文件名和文件锁适用于文件描述符的最大问题。因此,上述情况在以下情况下不起作用:

GC - open,
write - open
GC - lock, unlink, unlock, close // file still exists because held by write
write - lock, write, unlock, close // file removed

有人知道如何解决此类问题吗?是否有任何技巧可以结合文件锁定和文件删除或对文件进行原子操作?

笔记:

  • 我不想使用数据库,
  • 我正在寻找 Unix 的解决方案
  • 解决方案应适用于标准 POSIX 调用,如 fcnl、打开、关闭、取消链接

谢谢。

澄清主要问题是对文件的操作(名称 - 取消链接)应该通过文件描述符的操作原子地完成 - 锁定:

  • 打开,取消链接——处理文件
  • fnctl -- 处理描述符
4

1 回答 1

1

这不行吗?

write/read:
   fd=open(file_name,O_CREAT | O_RDWR); // create a new file or use exsting
   fcntl_lock_file(fd)
   if stat(file_name).{st_dev, st_ino} != fstat(fd).{st_dev, st_ino}
       unlock, close, retry
   save data to fd/read data from fd
   fcntl_unlock_file(fd)
   close(fd)

如果statEEXIST 失败(文件名不存在)或显示当前文件与您打开的文件不同,请保释。

于 2009-12-15T22:03:51.617 回答