c/c++;群集作为linux上的互斥对象文件删除不稳定

c/c++;群集作为linux上的互斥对象文件删除不稳定,c,linux,C,Linux,C语言中使用flock的文件锁定通常用于实现跨平台的协同进程间锁定/互斥 我有一个运行良好的实现(mac/linux/win),但它对文件删除并不健壮(至少在linux下是这样) 一个或多个进程已开始创建和使用锁文件(/tmp/lockfile),并在共享资源上与其协作互锁 一段时间后,我手动删除了锁文件(rm/tmp/lockfile)。正在运行的进程继续相互协作,但是任何想要开始使用相同资源锁和锁文件的新进程都会破坏整个互斥逻辑。它将创建一个新版本的/tmp/lockfile,该版本在某种程

C语言中使用
flock
的文件锁定通常用于实现跨平台的协同进程间锁定/互斥

我有一个运行良好的实现(mac/linux/win),但它对文件删除并不健壮(至少在linux下是这样)

一个或多个进程已开始创建和使用锁文件(
/tmp/lockfile
),并在共享资源上与其协作互锁

一段时间后,我手动删除了锁文件(
rm/tmp/lockfile
)。正在运行的进程继续相互协作,但是任何想要开始使用相同资源锁和锁文件的新进程都会破坏整个互斥逻辑。它将创建一个新版本的
/tmp/lockfile
,该版本在某种程度上与已在运行的进程中使用的版本有所不同

在任何进程打开锁文件时,可以采取哪些措施防止其被解除链接? 可以使用哪些其他解决方案


我不能使用信号量,因为如果所属进程崩溃,我需要锁自动释放。

您确实可以使用信号量。Linux提供了标志
SEM\u UNDO
,它将在进程终止时撤消信号量操作(请参见
semop
(2))。

rm命令实际上不会删除文件。相反,它将它们与文件系统断开链接,就像通过
unlink(2)
syscall一样。只要有任何进程保持文件打开(或存在指向文件的任何其他硬链接),文件就不会从磁盘中删除,而保持文件打开的进程将继续引用同一文件,即使该文件不再出现在目录列表中。没有任何东西可以阻止在与前一个文件相同的位置创建另一个文件并将其链接到文件系统,但这是一个完全不同的文件。这种行为对于一致的程序行为是可取的,有些程序有意将其用于管理临时文件

您无法阻止具有足够权限的进程取消锁定文件的链接。任何有足够权限创建锁文件的进程都有足够的权限取消它的链接,其结果如下所述。通常可以通过创建具有不可预测名称的临时文件来缓解此问题,以便与
flock()
一起使用,因此必须在希望通过锁定该文件来同步操作的进程之间交换文件名或打开的文件句柄。对于子进程的特定情况,您可以依赖子进程从其父进程继承打开的文件描述符,以使它们能够获取锁定文件,即使该文件已取消链接


另一方面,如果您依赖一个名为众所周知的锁定文件,那么解决方案可能是提前创建该文件,使root成为其所有者以及指向它的硬链接路径中每个目录的所有者,并拒绝所有其他用户对该文件和目录的写访问。如果你想更加小心的话,你可以考虑用强制访问控制(SELinux策略)来包装它。

谢谢。我必须尝试一下。锁文件名实际上是已知的和唯一的,@ MichelSanches,那么你的保护锁文件的选项是可以用来保护任何文件的。我的回答已经为该案例提供了建议。无论
flock()
ing如何,保持文件打开的进程都不会对取消链接提供保护。这是出于设计。是的,你的权利,我使用/tmp/xxx作为一个众所周知的好地方,任何用户都可以访问和创建文件。在这种情况下,root用户或任何用户决定清理/tmp,因为需要空间并阻止我的互斥逻辑:(使用精确属性创建文件作为root用户是个好主意,但它会工作吗?如果没有写“权限”,它会失败)。同时赋予文件root权限会使安装过程更加复杂,并且需要root权限。非常感谢您的建议,我必须尝试一下。@MichelSanches,如果进程无法写入锁定文件,那么您必须以模式
O_RDONLY
打开它,并且在打开的文件中不能包含
O_EXCL
滞后。包含
O_create
是没有用的,但也没有直接的危害。只要你成功打开文件,你就应该能够
flock()
它。我只是测试了这一点来确定。我用“rw-r-r”测试了打开根目录下的文件,当然只打开rd是可以的,但锁定不是失败的:(