文件r / w锁定和取消链接

时间:2009-12-15 21:45:07

标签: unix atomic nfs file-locking fcntl

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

我想要关注API:write(sid,data,timeout)read(sid,data,timeout)remove(sid) 其中sid ==文件名,我也希望有某种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,open,close,unlink

感谢。

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

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

1 个答案:

答案 0 :(得分: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)

如果stat因EEXIST而失败(文件名不存在)或显示当前文件与您打开的文件不同,则保释。