我在哪里可以找到一个备受推崇的参考资料,详细说明在Unix上正确处理PID文件?
在Unix操作系统上,通常的做法是使用特殊的锁文件"锁定"程序(通常是守护程序):PID文件.
这是一个可预测位置的文件,通常是"/var/run/foo.pid".程序应该在启动时检查PID文件是否存在,如果文件存在,则退出并显示错误.所以这是一种咨询,协作锁定机制.
该文件包含一行文本,是当前持有锁的进程的数字进程ID(因此名称为"PID文件"); 这允许一种简单的方法来自动发送信号到持有锁的进程.
我找不到的是处理PID文件的预期或"最佳实践"行为的良好参考.有各种细微差别:如何实际锁定文件(不要打扰?使用内核?平台不兼容性怎么办?),处理陈旧锁(默默删除它们?何时检查?),何时获取并释放锁等等.
在哪里可以找到一个受人尊敬的,最权威的参考(理想情况是在W. Richard Stevens的水平上)这个小题目?
首先,在所有现代UNIX上/var/run
都不会在重新启动后持续存在.
处理PID文件的一般方法是在初始化期间创建它并从任何出口(正常处理程序或信号处理程序)中删除它.
有两种规范的方法可以自动创建/检查文件.这些天最主要的是用O_EXCL
标志打开它:如果文件已经存在,则调用失败.旧方法(在没有系统的情况下O_EXCL
是必需的)是使用随机名称创建它并链接到它.如果目标存在,链接将失败.
据我所知,PID文件是一种惯例,而不是你可以找到一个受人尊敬的,主要是权威的来源.我能找到的最接近的是Filesystem Hierarchy Standard的这一部分.
这个Perl库可能会有所帮助,因为看起来作者至少考虑过一些可能出现的问题.
我相信/ var/run下的文件通常由发行版维护者而不是守护进程的作者处理,因为发行版维护者有责任确保所有的init脚本能够很好地协同工作.我检查了Debian和Fedora的开发人员文档,找不到任何详细的指导,但您可以在他们的开发人员的邮件列表上获得更多信息.
请参阅Kerrisk的Linux编程接口,第55.6节"仅运行一个程序实例",它基于Stevens的Unix网络编程v2中的pidfile实现.
另请注意,pid文件的位置通常由发行版(通过init脚本)处理,因此编写良好的守护程序将使用命令行参数指定pid文件,并且不允许配置文件意外覆盖它.它还应该优雅地自己处理过时的pid文件(不应该使用O_EXCL).应该使用fcntl()文件锁定 - 您可以假设守护程序的pidfile位于本地(非NFS)文件系统上.
根据分发,它实际上是处理pidfile的init脚本.它会在启动时检查是否存在,在停止时检查等等.我不喜欢这样做.我编写自己的init脚本,通常不使用stanard init函数.
一个编写良好的程序(守护进程)将有一些配置文件说明应该写这个pidfile(如果有的话).它还需要注意建立信号处理程序,以便在可以处理信号时,在正常或异常退出时清除PID文件.然后,PID文件为init脚本提供正确的PID,以便可以停止它.
因此,如果pidfile在启动时已经存在,则它是程序之前崩溃的一个非常好的指示器,应该进行某种恢复工作(如果适用).如果您有init脚本本身检查PID的存在或取消链接,那么您可以在脚中拍摄该逻辑.
就名称空间而言,它应该遵循程序名称.如果你正在启动'foo-daemon',它将是foo-daemon.pid
您还应该探索/ var/lock/subsys,但这主要用于Red Hat风格.