Linux 中的跨进程锁定

Joh*_*ohn 4 linux mutex

我希望在 Linux 中创建一个应用程序,其中一次只能运行一个应用程序实例。我想让它变得健壮,这样如果应用程序的一个实例崩溃,它就不会无限期地阻止所有其他实例。我真的很感激一些关于如何做到这一点的示例代码(因为网上有很多关于这个主题的讨论,但我在尝试时找不到任何有效的东西)。

Mak*_*zin 5

您可以使用 Linux 提供的文件锁定工具。您还没有指定语言,但是您可能会发现这种功能几乎无处不在,以某种形式存在。

下面是如何在 C 程序中执行此操作的简单想法。当程序启动时,您可以使用系统调用对整个文件进行独占非阻塞锁定fcntl。当尝试启动应用程序的另一个实例时,尝试锁定文件时会出现错误,这意味着该应用程序已经在运行。

这是一个如何使用完整文件锁定的小示例fcntl(该函数提供了放置字节范围锁的设施,但当长度为0时,整个文件被锁定)。

   struct flock lock_struct;

   memset(&lock_struct, 0, sizeof(lock_struct));

   lock_struct.l_type = F_WRLCK;
   lock_struct.l_whence = SEEK_SET;
   lock_struct.l_pid = getpid();

   ret = fcntl(fd, F_SETLK, &lock_struct);
Run Code Online (Sandbox Code Playgroud)

请注意,您需要先打开文件才能加锁。这意味着您需要有一个文件来用于锁定。将其放置在不会对其他应用程序造成任何干扰/混乱的地方可能会很有用。

当进程终止时,它所获取的所有锁都将被释放,因此不会阻塞任何内容。

这只是其中之一的想法。我很确定还有其他方法。


jma*_*man 5

执行此操作的传统 UNIX 方法是使用PID 文件

在进程启动之前,它会检查预先确定的文件是否通常/var/run/<process_name>.pid存在。如果找到,则表明进程已经在运行并且该进程退出。

如果该文件不存在,则这是第一个运行的进程。它创建该文件/var/run/<process_name>.pid并将其 PID 写入其中。该进程在退出时取消文件链接。

更新:

为了处理守护进程崩溃并留下 pid 文件的情况,如果找到 pid 文件,可以在启动期间进行额外的检查:

  • 执行ps并确保具有该 PID 的进程不存在
  • 如果存在,请确保它是一个不同的进程
    • 从上述ps输出
    • /proc/$PID/stat

  • 这并没有解释如何自动从崩溃的进程中恢复。如果进程异常退出,该文件仍然存在。 (2认同)