我正在使用Ubuntu 22.04.1
(WSL 2
尽管事实上它只Unix
与这个问题相关)
为什么当我们tmux
从zsh
会话运行时,进程树(我稍微删节了)从
init(Ubuntu)─┬─SessionLeader───Relay(9)─┬─ssh-agent
└─zsh───pstree
到
init(Ubuntu)─┬─SessionLeader───Relay(9)─┬─ssh-agent
├─tmux: server───zsh───pstree
└─zsh───tmux: client
这里,pstree
只是告诉我进程树的命令,因此它出现在上面。
当我们运行tmux
in时zsh
,会发生zsh
运行fork()
创建一个派生进程,该进程是zsh
(即tmux: client
上面)的子进程。我不确定这个tmux: server
与产生它的进程同级的进程是如何形成的。
答案1
对于服务器,tmux
将自身分叉两次,以便将自身守护进程化,并为其启动的会话分离自身。
孩子死了,孙子运行服务器。这意味着服务器没有父服务器。
init
没有父进程的进程通常由id 1 的进程采用。在 Linux 上,某些进程可以被指定为父进程儿童副收割者使用PR_SET_CHILD_SUBREAPER
prctl()
为它的后代承担这个角色。
您在这里观察到的可能是 WSL 的类似情况。这个Relay(9)
过程大概是一个儿童副收割者并采用了该tmux
服务器守护进程。
你可以分辨出谁是儿童副收割者在你的祖先中,有这样的东西:
((zmodload zsh/system; sleep 0.2; echo $sysparams[ppid])&) | cat
我希望它能返回Relay(9)
进程的 pid。
您可以tmux
通过在下面运行它来遵循此处的操作:
strace -fo log -e clone,exit_group,prctl tmux
然后检查文件的内容log
。你会看到类似的东西:
3908 execve("/usr/bin/tmux", ["tmux"], 0x7fffd0c3e990 /* 50 vars */) = 0
3908 prctl(PR_SET_NAME, "tmux: client") = 0
家长是客户。
3908 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f54afe20a10) = 3909
3909 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f54afe20a10) = 3910
为服务器分叉两次。
3909 exit_group(0) = ?
孩子终止。
3910 prctl(PR_SET_NAME, "tmux: server") = 0
孙子(此时已经失去了上面的父母并被收养了) 儿童副收割者)运行服务器。
[...]
3910 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f54afe20a10) = 3911
3911 execve("/bin/zsh", ["-zsh"], 0x55bee5bdd170 /* 54 vars */) = 0
服务器分叉一个进程来$SHELL
在第一个窗格中运行您的进程。