【问题标题】:Python's daemon PPID not equal to 1Python 守护进程 PID 不等于 1
【发布时间】:2017-09-09 10:54:44
【问题描述】:

在 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 - 包括守护进程?它是守护进程的正确行为吗?


相关问题:

【问题讨论】:

    标签: python linux pid systemd python-daemon


    【解决方案1】:

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

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

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

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

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

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

    您可以向那些出错的手册发布错误报告吗?

    【讨论】:

    • 我不认为它像你说的那么随意。 Linux内核在几个地方提到init是PID 1:“我们需要先产生init,以便它获得pid 1”init/main.c),“init真的需要pid 1" (kernel/pid.c), "系统中总是至少有一个任务 (init, pid == 1)" (kernel/cgroup/cgroup.c)。
    【解决方案2】:

    简短的回答是:没关系。

    重要的是所有守护进程都有一个像init 这样的父进程,它会在孩子死后通过调用wait() 来收割子进程。否则进程退出时会变成僵尸

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

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

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

    【讨论】:

    • init 获得 PID 1 也是偶然的:因为它是内核运行的第一个用户空间进程,并且在系统在线时它永远不会退出。由于任何其他原因,PID 1 并不特殊;同样,systemd 的 PID 并不特殊。
    猜你喜欢
    • 2013-06-17
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2014-10-20
    • 2014-08-30
    • 1970-01-01
    相关资源
    最近更新 更多