【问题标题】:Emulate Windows-style file locking on Linux and OS/X [closed]在 Linux 和 OS/X 上模拟 Windows 样式的文件锁定 [关闭]
【发布时间】:2017-03-15 09:44:35
【问题描述】:

我正在尝试在 Linux 上获得与 Windows 提供的文件锁定语义接近的文件锁定语义,目的是在缓存文件由单独的进程打开时不删除它们。我的程序创建了各种临时缓存文件,我想在它关闭时删除它们,但是多个实例可能同时运行,我不想删除另一个实例正在使用的文件,因为它会破坏语义 - 缓存文件在各个点按名称打开,如果删除,它将中断。我知道 Linux 在关闭所有打开的句柄之前不会物理删除文件,但我仍然需要按名称打开它。

每个文件的名称唯一标识内容,即我知道如果我需要数据X,它在名为hash(X)的缓存文件中,因此当前实例是否是创建它的实例无关紧要,或者如果我正在重用由另一个实例创建的文件。显然它不完全是数据的哈希值,因为如果我有数据,我就不需要缓存文件,但足以说明重用缓存文件是我想要的。

我的问题是我还没有找到一种在打开文件后用flock 锁定文件的无竞争方式。在这两个调用之间,另一个进程可能会完成并运行缓存清理操作,该操作会删除我刚刚创建的文件。我不需要像在 Windows 上那样强制锁定,因为它只是我的程序访问这些文件,但我确实需要一种方法来防止实例相互踩踏。

编辑:我正在使用 C。

【问题讨论】:

  • 您没有说明语言/环境?也许使用计数信号量。
  • 看mtime和ctime;如果您避免删除在过去一分钟内创建或修改的文件,您就可以了。或者过去的一天。
  • 这是非常特定于 Linux 的,但已知可以在类似的情况下工作。安装SIGIO 处理程序(空函数很好),并使用fcntl(fileno(handle), F_SETLEASE, F_WRLCK) 对文件进行写租约。只有当文件未被任何其他进程打开时,它才会成功。 (这确实要求该文件由与正在运行的进程相同的用户拥有,或者该进程以超级用户权限运行。)如果您确实获得了文件租约,unlink()/remove() 文件名和@987654326 @;否则只是fclose(handle)

标签: c linux file-locking


【解决方案1】:

我不想删除另一个实例正在使用的文件

不能删除另一个进程(甚至是同一个进程)使用的文件。您可以删除指向该文件的目录条目(或者更确切地说是 a 目录条目,因为可能有多个),但文件本身将保持活动状态,只要它保持打开状态 任何进程。 Linux 中的文件是引用计数的,这就是它的工作原理。

按名称协作“锁定”文件的一种简单方法是:

    char new_filename[FILENAME_SIZE] = "busy_";
    link (filename, strcat(new_filename, filename));
    fd = open(new_filename, "r");
    if (fd) {
        ......
        close (fd);
    }
    unlink (new_filename);

检查link的结果。如果每个人都这样做是为了打开一个文件,并且清理只取消了原始名称的链接,那么你就设置好了。

【讨论】:

  • 是的,我知道。这就是为什么我特别说我仍然需要从同一个进程中按名称打开它。基本上,发生的事情是程序的一部分生成文件名并打开它,并在使用期间保持打开状态。然后另一部分再次按名称打开它。如果在这两点之间删除了目录条目,则第二次打开将失败。
  • 很抱歉错过了这部分:“缓存文件在各个点按名称打开”。这看起来像真正的问题。为什么要这样做?为什么没有打开文件的每个进程注册表?
猜你喜欢
  • 2010-12-29
  • 2018-11-16
  • 1970-01-01
  • 2011-04-13
  • 2011-08-13
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 2012-11-16
相关资源
最近更新 更多