Python的守护进程PPID不等于1

时间:2017-04-13 10:47:56

标签: python linux pid systemd python-daemon

在Linux中创建守护进程是quite complex问题,但在daemon(7) manual中有很好的记录。值得庆幸的是,Python 2和3的python-daemon模块实现了PEP3143,所以我正在使用它。

问题出在这里:当我使用python-daemon模块时,我很惊讶守护程序的PPID 1。为什么呢?

简单示例:

import daemon
import time
import os

with open('/tmp/test.log', 'w') as logfile:
    c = daemon.DaemonContext(stdout=logfile)
    with c:
        print('In daemon...')
        for i in range(10):
            print('My PID is {}, PPID is {}'.format(os.getpid(), os.getppid()))
            time.sleep(2)

启动上述脚本20秒后test.log的内容(我推荐tail -f /tmp/test.log):

In daemon...
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736
My PID is 31397, PPID is 1736

事实证明,PID 1736的过程为/lib/systemd/systemd

patryk@mycomp:/tmp$ ps -fq 1736
UID        PID  PPID  C STIME TTY          TIME CMD
patryk    1736     1  0 kwi12 ?        00:00:00 /lib/systemd/systemd --user

最近我在C(在安装了systemd的同一台机器上)和AFAIR所有守护进程PPID = 1中实现了守护进程。我遇到的所有手册都提到守护进程的PPID始终是1

systemd是否改变了它? systemd是否为所有进程(包括守护进程)处理awaits?这是守护进程的正确行为吗?

相关问题:

2 个答案:

答案 0 :(得分:3)

简短的回答是:没关系。

重要的是,所有守护进程都有一个像init这样的父进程,通过调用wait()可以在死亡时收获它们。否则,该过程将在退出时变为 zombie

将父PID设置为1并没有什么特别之处。您链接到的手册页说这个过程对于旧的SysV风格的守护进程来说是PID 1,但对于新的SystemD风格的守护进程却没有这么说。 init始终作为PID 1运行,而传统上它是守护进程的父级。但它不需要

systemd --user管理用户服务。因此,当您运行它(作为用户)时,为什么这个进程成为您的守护进程的父进程是有道理的。

在阅读关于* nix的文档时必须要小心,这个平台已经存在了几十年。事情发生变化,手册变得过时,或者可能在错误的环境中被解释。 SystemD为Linux平台的很多事情带来了重大变化。

答案 1 :(得分:0)

  

我遇到的所有手册都提到守护程序的PPID始终为1。

这些手册不正确;守护程序获取任何父级来管理分离的进程。

如果可能是init进程,并且如果init 可能具有 PID 1,那么它将是守护进程的PPID;但两者都是任意的,而不是定义性的。手册不应暗示其他含义。

init进程通常仅获得PID 1(并且显然没有例外),因为任意地,第一个用户空间进程被分配了PID 1,而恰好是init ,然后在主机在线时永不退出。否则PID 1没有什么特别的。

systemd进程将同样获得为其启动时间分配的任意PID。

其他流程管理器(例如runit)在启动时也会类似地获得任意PID。

您可以将错误报告发布到发现错误的手册中吗?