4

如果文件不存在,我需要创建一个文件,以使另一个尝试创建此文件的进程会失败。即使在创建过程完成将实际数据写入文件之前,我也需要将文件视为“已创建”。

我阅读了关于O_EXCLflag to 的信息open(),所以似乎存在解决方案,但是我有几个问题:

  1. 你有这种技术的经验吗?它有多好?(我想我不能拥有数据库级别的原子性,但足够好是......好吧,足够了)
  2. 之后我应该立即关闭文件open()以使其被视为已创建,然后重新打开以进行写入吗?
  3. 有什么微妙之处需要注意吗?
4

2 回答 2

7

open() 手册页说您的方法在 NFS 上可能会失败。

从 O_EXCL 部分:

当与 O_CREAT 一起使用时,如果文件已经存在,则它是一个错误并且 open() 将失败。在这种情况下,存在一个符号链接,不管它指向哪里。O_EXCL 在 NFS 文件系统上被破坏;依赖它来执行锁定任务的程序将包含竞争条件。

它提出了一个更通用的解决方案:

使用 lockfile 执行原子文件锁定的解决方案是在同一文件系统上创建一个唯一文件(例如,合并主机名和 pid),使用 link(2) 链接到 lockfile。如果link() 返回0,则锁定成功。否则,对唯一文件使用 stat(2) 来检查其链接数是否增加到 2,在这种情况下,锁定也是成功的。

有关各种问题和方法的更多详细信息,请参阅此网页的“将文件用作锁”部分。

于 2011-03-06T14:12:19.067 回答
1

POSIX说:

如果设置了 O_CREAT 和 O_EXCL,如果文件存在,则 open() 将失败。检查文件是否存在以及如果文件不存在则创建文件对于执行 open() 的其他线程在同一目录中命名相同文件名并设置了 O_EXCL 和 O_CREAT 应该是原子的。

所以其他使用的进程O_EXCL会认为它在创建后立即打开。

于 2011-03-06T14:53:31.130 回答