Python 的守护程序 PPID 不等于 1

Python's daemon PPID not equal to 1

在 Linux 中创建守护进程是 quite complex issue, but it's very well documented in daemon(7) manual. Thankfully there is python-daemon module for Python 2 and 3 that implement PEP3143,所以我正在使用它。

问题来了:我在玩python-daemon module I was surprised that daemon's PPID is not 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 (on the same machine with systemd installed) and AFAIR all daemons had PPID = 1. All manuals I came across mention that daemon's PPID is always 1.

中实现守护进程

systemd changed it? Does systemd process awaits 是否适用于所有进程——包括守护进程?这是守护进程的正确行为吗?


相关问题:

简短的回答是:没关系。

重要的是,所有守护进程都有一个像 init 这样的父进程,当他们死亡时,会通过调用 wait() 获得子进程。否则进程退出时会变成zombie

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

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

阅读关于 *nix 的文档时一定要小心,*nix 是一个已经存在了几十年的平台。事情发生变化,手册变得过时,或者可以在错误的上下文中进行解释。 SystemD 对 Linux 平台的 很多 方面进行了重大更改。

All manuals I came across mention that daemon's PPID is always 1.

那些手册不正确;守护进程获取任何父进程将要管理的分离进程。

如果 恰好是 init 进程,并且如果 init 恰好具有 PID 1 ,那么这将是守护进程的 PPID;但这两者都是任意的,而不是定义性的。手册不应另有暗示。

init 进程通常只获得 PID 1(显然没有例外),因为任意地,第一个用户-space 进程被分配 PID 1,而这恰好是 init,当主机在线时它永远不会退出。否则 PID 1 没有什么特别的。

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

其他进程管理器,例如runit,在启动时同样会得到一个任意的PID。

你能post向那些错误的手册报告错误吗?