4

在 Linux 中创建守护进程是一个相当复杂的问题,但它在daemon(7) manual. 值得庆幸的是python-daemon,Python 2 和 3 的模块实现了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)

test.log启动上述脚本 20 秒后的内容(我推荐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所有进程——包括守护进程?这是守护进程的正确行为吗?


相关问题:

4

2 回答 2

3

简短的回答是:没关系。

重要的是,所有守护进程都有一个父进程init,当他们死去时,他们会通过调用wait(). 否则进程退出时会变成僵尸。

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

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

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

于 2017-04-13T11:04:42.993 回答
0

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

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

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

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

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

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

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

于 2019-02-11T20:14:48.900 回答