在Linux上编写PID文件

5

我目前正在开发一个需要单实例(即限制为1个用户1个进程)的Linux守护程序。有没有更好的方法来实现,而不必使用 getpid() 手动将pid写入 /var/run/ ,然后使用 flock() 进行锁定?


2
你不必编写pid文件,但你必须使用某种类型的锁文件。 - Marc B
编写PID的优点在于您可以检查进程是否真正处于活动状态并运行良好... - Flexo
2
@awoodland:不行,你不能这样做。进程ID(pid)除了对于该进程的直接父进程有用之外,其他情况下使用都会导致竞争条件,误报某个进程仍然存在,甚至可能发出错误的信号给其他进程。只有在成功调用“wait”系列函数后,才能确保pid不会被重复使用。 - R.. GitHub STOP HELPING ICE
4
如果您想检查进程是否仍在运行,可以让您的守护进程打开并锁定一个文件。当进程终止时,锁将自动释放,不存在竞争条件。同样的效果也可以通过Unix套接字、鲁棒的互斥锁以及其他几种类似机制来实现。 - R.. GitHub STOP HELPING ICE
5个回答

3

1

我在写的一些initd脚本中使用类似这样的东西。将COMMAND替换为您需要的内容。

PIDFILE=/var/run/service.pid
COMMAND="java -jar start.jar"
$COMMAND > /dev/null 2>&1 &
echo $! > $PIDFILE

根据@dogane的建议进行了编辑,并进行了测试。


1
$!会给你进程ID,你不需要使用grep ps。 - dogbane
1
这个失败了,是一个经典的竞态条件。不能保证只有一个COMMAND实例在运行。 - William Pursell
诚然,这只是对他问题的部分回答,但它展示了如何编写pid文件。我将其用作启动脚本,与实际检查进程是否已在运行的init脚本一起使用。如果@Error1f1f还没有离开,今晚我有时间会发布那段代码。 - Jeff Busby

1

只需使用libunique。这是最简单的方法。


那看起来真的很有趣,但是除非我漏掉了什么,否则它似乎与GNOME紧密相关? - Flexo
这取决于GTK,而不是Gnome。很难找到没有GTK的Linux桌面。但是,如果您要在无头服务器上使用您的守护程序,libunique并不是最佳选择。 - E. Verda

1

只需锁定可执行文件本身。


这么做不会限制整个系统只能有一个实例吗?也就是说,两个不同的用户不能在同一个系统上拥有自己的实例了? - Pihhan

0

如果你真的不能使用锁文件,可以使用套接字代替。另一个实例将无法启动,因为地址已经在使用中。


我想你的意思是绑定一个套接字。 - Matt Joiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接