在 zsh 中运行 tmux 的子进程和同级进程

在 zsh 中运行 tmux 的子进程和同级进程

我正在使用Ubuntu 22.04.1WSL 2尽管事实上它只Unix与这个问题相关)

为什么当我们tmuxzsh会话运行时,进程树(我稍微删节了)从

init(Ubuntu)─┬─SessionLeader───Relay(9)─┬─ssh-agent
                                        └─zsh───pstree

init(Ubuntu)─┬─SessionLeader───Relay(9)─┬─ssh-agent
                                        ├─tmux: server───zsh───pstree
                                        └─zsh───tmux: client

这里,pstree只是告诉我进程树的命令,因此它出现在上面。

当我们运行tmuxin时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在第一个窗格中运行您的进程。

相关内容