我希望在 Linux 中制作一个应用程序,一次只能运行一个应用程序实例。我想让它变得健壮,这样如果应用程序的一个实例崩溃,它就不会无限期地阻止所有其他实例。我真的很感激一些关于如何做到这一点的示例代码(因为网上有很多关于这个话题的讨论,但是当我尝试它时我找不到任何有用的东西)。
2 回答
您可以使用 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);
请注意,您需要先打开文件才能加锁。这意味着您需要有一个用于锁定的文件。将它放在不会对其他应用程序造成任何分心/混乱的地方可能会很有用。
当进程终止时,它所占用的所有锁都将被释放,因此不会阻塞任何东西。
这只是其中一种想法。我很确定还有其他方法。
执行此操作的传统 UNIX 方法是使用PID 文件。
在一个进程开始之前,它会检查一个预先确定的文件 - 通常是否/var/run/<process_name>.pid
存在。如果找到,则表明进程已经在运行并且该进程退出。
如果文件不存在,这是第一个运行的进程。它创建文件/var/run/<process_name>.pid
并将其 PID 写入其中。该过程在退出时取消链接文件。
更新:
为了处理守护进程崩溃并留下 pid 文件的情况,如果找到 pid 文件,可以在启动期间进行额外的检查:
- 执行
ps
并确保不存在具有该 PID 的进程 - 如果存在,请确保它是一个不同的过程
- 从上述
ps
输出 - 从
/proc/$PID/stat
- 从上述