【问题标题】:Preventing opening file twice from different processes防止从不同进程两次打开文件
【发布时间】:2014-11-12 11:59:24
【问题描述】:

经过我的研究,我仍然不确定是否有 API 允许您以独占方式打开文件,这意味着任何其他进程都无法访问该文件。 请问有人可以给我一个很好的参考/指南/说明/手册来涵盖这个主题吗?
非常感谢!

编辑:建议锁定就足够了。

【问题讨论】:

  • 您的意思是“完全”,而不是“过度”,对吧?
  • @trojanfoe - 当然。谢谢
  • C++ 库(即std::[io]fstreamfopen)中没有任何东西支持这一点。在系统级别,它取决于系统:Windows 有,Unix 没有。

标签: c++ c macos file-locking


【解决方案1】:

进程之间的文件锁定主要有三个系统:

一些类 Unix 系统可能没有flock();例如,他们可能有lockf(),或者他们可能只有fcntl() 锁定(尽管大多数人会同时拥有lockf()fcntl(),而且许多人也会拥有flock())。当前版本的 POSIX 要求 fcntl() 锁定和 lockf() 锁定用于文件级进程间锁定。 (POSIX 还定义了flockfile()funlockfile()ftrylockfile() — 用于控制应用程序中线程之间的锁定)。

AFAIK,您可以使用 fcntl() 锁定来实现 lockf()flock() 锁定。

请注意,锁定功能适用于文件描述符或文件流。每个程序都可以打开该文件,但随后会应用咨询锁定调用来检查它是否具有对该文件的独占访问权限。

请注意,某些系统支持强制文件锁定(通过在文件上设置 setgid 位来指示,而未设置相应的组执行位 - 例如 2644 模式)。但是,Mac OS X 不支持强制锁定(10.10 Yosemite 测试过,但之前的版本也有这个限制)。 POSIX 不需要强制锁定支持。它是在 SVR4 系统上提供的。

【讨论】:

    【解决方案2】:

    为了防止多个进程读取文件,所有进程都必须实现相同的锁定机制。

    一种方法是使用flock 机制,该机制并非随处可用。来自flock(2)手册页:

    CONFORMING TO
        4.4BSD (the flock() call first appeared in 4.2BSD).
        A version of flock(), possibly implemented in terms of fcntl(2),
        appears on most UNIX systems.
    

    另一种方法是使用 lockfile -- 与原始文件并排的文件表明锁处于活动状态。 C11 为fopen 中的模式指定了一个修饰符x,它确保文件始终被创建,如果文件已经存在则不打开:

    FILE * f = fopen("filename.lock", "wx");
    if (!f) {
        // File already exists!
        return 0;
    }
    
    // Do stuff
    fclose(f);
    remove("filename.lock");
    

    【讨论】:

    • 你的意思是flock不是随处可见的?
    • @Sanich 它不是 C/C++ 标准的一部分,因此它是特定于环境的。见添加flock(2) manpage sn-p
    • @Sanich:一些类Unix系统可能没有flock();例如,他们可能有lockf(),或者他们可能只有fcntl() 锁定。当前版本的 POSIX 强制要求 fcntl() 锁定和 lockf() 锁定(以及 flockfile()funlockfile()ftrylockfile() — 我刚刚遇到过;它们用于控制应用程序中线程之间的锁定)。 AFAIK,您可以使用fcntl() 锁定来实现lockf()flock() 锁定。
    • @JonathanLeffler 有趣的函数,我不知道lockf(3) 获得强制锁。
    • AFAICT, lockf() 仅在支持强制锁定的系统上对具有适当强制锁定权限(setgid 位设置、组执行位重置)的文件应用强制锁定。 POSIX 不需要支持强制锁定。 SVR4(Unix System V 第 4 版)确实提供了强制锁定,并且由此衍生的系统(AIX、HP-UX、Solaris ……)可能仍然支持它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多