如何针对外部进程锁定文件


How to lock a file against external processes

我需要创建一个其他脚本或进程无法删除的锁定文件。我试过这个:

    $f = fopen($pidFile, 'w');
    fwrite($f, getmypid());
    flock($f, LOCK_EX);

但是从当前用户启动的任何其他进程都可以删除CCD_ 1文件,即使文件句柄仍然被正在运行的脚本打开。如何解决这个问题并防止其他人(即非PHP进程也)删除该文件?当进程退出时,要自动释放的锁是什么?所有类似的问题都以RTM flock()结尾,但没有一个问题回答如何针对外部进程锁定文件。

操作系统为Linux 2.6.32-431.el6.x86_64

Linux上的

flock默认使用"咨询锁定",这意味着它不会阻止任何其他进程操作该文件。请参阅PHP手册中的注释。

flock()在Windows上使用强制锁定而不是建议锁定。在基于Linux和System V的操作系统上,强制锁定也通过fcntl()系统调用支持的常见机制得到支持:也就是说,如果有问题的文件设置了setgid权限位,并且清除了组执行位。在Linux上,文件系统还需要安装mand选项才能正常工作。

另请参阅https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt

通过在文件模式中设置组id位但删除组执行位,将文件标记为强制锁定的候选文件。这是另一个毫无意义的组合,并且被System V的实现者选择以中断现有的用户程序。

请注意,当写入一个setgid文件。这是一种安全措施。内核已经修改为识别强制锁定候选者的特殊情况,并不要清除这个位。类似地,内核没有被修改以运行具有setgid权限的强制锁定候选者。

还要注意警告:

即使是root用户也无法覆盖强制锁,因此失控的进程可能会造成如果他们锁定了关键文件,就会造成严重破坏。解决方法是更改文件权限(删除setgid位),然后再尝试读取或写入。