文件读/写锁定和取消链接

发布于 2024-08-15 04:02:50 字数 1230 浏览 13 评论 0原文

我有以下问题。我想创建一个基于文件系统的会话存储,其中每个会话数据都存储在以会话 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 - 对描述符进行操作

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 NFS.

The simplest solution I thought about was:

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)

The biggest issue that file unlinking works on file names and file locks work on file
descriptors. So the above would not work in following scenario:

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

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?

Notes:

  • I don't want to use Database,
  • I look for a solution for Unix
  • Solution should work with standard POSIX calls like fcnl, open, close, unlink

Thanks.

Clearification the major issue is that operation on files (names -- unlink) should be done atomically with operation of file descriptors -- locking:

  • open, unlink -- work on files
  • fnctl -- work on descriptors

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹沉浮 2024-08-22 04:02:50

这不行吗?

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(文件名不存在)或显示当前文件与您打开的文件不同,请保释。

Wouldn't this work?

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)

If stat fails with EEXIST (file name does not exist) or shows that the current file is not the same as the one you opened, bail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文