不存在的 sid/pgid 进程如何可能?

Ddo*_*rda 3 process proc

我在 Ubuntu 17.04 上列出了进程,注意到以下进程:

root@user-virtual-machine:~# ps  xao pid=,ppid=,pgid=,sid=
1603      1   1601   1601
Run Code Online (Sandbox Code Playgroud)

但是进程 1601 不存在。

root@user-virtual-machine:~# ls /proc/1601
ls: cannot access '/proc/1601': No such file or directory
Run Code Online (Sandbox Code Playgroud)

正如你所看到的 /proc/1603/status 仍然引用 1601。

root@user-virtual-machine:~# cat /proc/1603/status
Name:   VGAuthService
Umask:  0000
State:  S (sleeping)
Tgid:   1603
Ngid:   0
Pid:    1603
PPid:   1
TracerPid:  0
Uid:    0   0   0   0
Gid:    0   0   0   0
FDSize: 64
Groups:  
NStgid: 1603
NSpid:  1603
NSpgid: 1601
NSsid:  1601
Run Code Online (Sandbox Code Playgroud)

重要的是,我在主机上(不在容器内)。

怎么可能?如何为不存在的进程设置 setid/setpgid?

Sté*_*las 5

是的,这是一个没有领导者的会话,这对于守护进程来说很常见。

会话主要用于在终端上实现登录会话。

当您从终端启动守护程序时,您希望它与终端断开连接。要使该守护进程的进程不再将终端作为其控制终端,您需要启动一个新会话。因此,通常守护进程会 fork 一个进程(这确保子进程不是进程组领导,并且父进程可以退出),并调用setsid()该子进程。

该孩子将成为新会话的领导者,因此不是由终端控制的会话。但是,如果该进程在没有传递 O_NOCTTY 标志的情况下打开了另一个终端设备,则会导致该终端成为该会话的控制终端,这不是您想要的守护进程。为了确保它不会发生,最好再次分叉,然后孩子不再是会话领导者,打开终端设备将无害。

父节点没有理由徘徊并退出,因此该会话不再有领导者。

所以守护进程在没有领导者的情况下运行是很常见的。

在这里,在没有领导者的会话中寻找进程,我看到了很多守护进程:

$ ps -je | grep -wf <(comm -23 <(ps -eo sid= | sort -u) <(ps -eo pid= | sort -u) | awk '$1{print $1}')
 1722  1714  1714 ?        00:00:01 atopacctd
 2540  2178  2178 ?        00:00:00 ddclient - slee
 2985  2984  2984 ?        00:00:00 dnsmasq
 2987  2984  2984 ?        00:00:00 dnsmasq
 8428  8427  8427 ?        00:00:00 gnome-keyring-d
 8726  8725  8725 ?        00:01:17 pulseaudio
11456 11455 11455 ?        00:00:00 gnome-keyring-d
11649 11648 11648 ?        00:00:00 pulseaudio
Run Code Online (Sandbox Code Playgroud)