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

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

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

root@user-virtual-machine:~# ps  xao pid=,ppid=,pgid=,sid=
1603      1   1601   1601

然而进程1601不存在。

root@user-virtual-machine:~# ls /proc/1601
ls: cannot access '/proc/1601': No such file or directory

正如你所看到的 /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

值得一提的是,我在主机上(而不是在容器内)。

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

答案1

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

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

当您从终端启动守护程序时,您希望它与终端断开连接。为了使该守护进程的进程不再将终端作为其控制终端,您需要启动一个新会话。因此,守护进程通常会分叉一个进程(这确保子进程不是进程组领导者,以便父进程可以退出),并调用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

相关内容