据我所知,shell 及其子进程位于同一会话中,具有相同的(控制)终端。我读到它们是交互式进程,因为它们具有关联的相同终端。目前,我接受它,尽管感觉不太对劲,因为真正的交互是在用户和 shell 之间。
GUI程序(例如浏览器、文本编辑器)、窗口管理器和桌面环境怎么样?它们是 X11 的子进程吗?
更正:shell 中的每个命令管道都有不同的 PGID。因此,shell 的子进程与 shell 的子进程没有相同的 PGID。
答案1
传统的 Unix 概念会议对于文本终端上的登录会话有意义。
在 X11 会话中(即会议在一般意义上,而不是在特定的 Unix 意义上),所有进程通常都是会话领导者进程的后代。这可以是会话管理器(如果有)、窗口管理器或启动器(图形外壳)(如果有)。有一个进程启动 X11 会话,其死亡会结束该会话,但其角色因桌面环境而异。
pstree
您可以使用(可能不是默认安装的一部分)或ps axf
(仅限 Linux)来观察进程树。 X 服务器与其他程序不属于同一树分支;它的作用只是协调输入和输出,它从不参与启动程序。通常您会看到一个xinit
或一个显示管理器有两个孩子,一个是 X 服务器,另一个是 X 会话领导者。
如果某些 GUI 程序的父进程已死亡(例如,因为它们是由包装脚本在后台启动,然后退出),则某些 GUI 程序可能不会附加到该进程树。
真正的交互是在用户和 shell 之间。
仅当您实际与 shell 交互时。当您与终端中运行的另一个程序交互时,不涉及 shell。输入和输出直接在程序和终端之间进行,shell 只是坐在后台等待程序退出或挂起。
答案2
编辑:我最初误读了这个问题。
X windows 是一个显示服务器。客户端应用程序使用消息与服务器进行通信。这些进程通常没有关联的终端,因为它们的所有输入都来自 X。如果应用程序需要终端,则会创建一个伪终端并将其与应用程序关联,例如 gnome-shell 创建一个 pty 并将 bash 与其关联。
原始:shell(启用作业控制)为它创建的每个子进程创建一个进程组。 x 应用程序与 x11 通信,即不由 x11 执行。
答案3
任何常规进程(包括 GUI 进程)都可以将自己声明为会话领导者(例如在 python 中通过os.setpgrp()
),并且默认情况下,在那一刻之后生成的子进程(及其所有后代)将属于其新会话组,而不是其原始会话组(当然,那些本身成为会议主持人的人除外)。新会话组的 pgid 通常(或始终不是 100% 确定)是自称为会话领导者进程的 pid。
这是一个实际的例子:
$ ps -eo pid,ppid,pgid,tty,cmd | egrep "(PPID|konsole|Running)"
PID PPID PGID TT CMD
4841 9633 4840 pts/3 grep -E (PPID|konsole|Running)
7375 1 7374 pts/3 konsole -p name=ROOT -e su -
9373 1 9373 ? kdeinit4: kdeinit4 Running...
9489 1 9373 ? kdeinit4: konsole [kdeinit] -session 102172181df177000142160830700000083410009_14428560
9492 1 9373 ? kdeinit4: konsole [kdeinit] -session 102172181df177000142901958900000018140011_14428560
9558 1 9373 ? kdeinit4: konsole [kdeinit] -session 102112051ed1c6000144239124800000016680010_14428560
列出的大多数konsole
进程都是由 KDE 本身通过 (pid 9373) 启动kdeinit
并继承其 pgid 9373。
然而,konsole
pid 7375(显示在同一显示器上并由 KDE 控制,就像其他 GUI 应用程序一样)是从在其他konsole
进程之一中运行的 shell 手动启动的。它属于 pgid 7374,当该konsole
进程本身被分叉时启动(由其父 pid 7374,现已不复存在,当时成为会话领导者)。
与控制终端无关(例如,这些 konsole 进程内的每个 shell 都有自己的 tty,但只有手动启动的 konsole 进程才有一个 - pty/3,从其祖先 shell 继承,KDE 启动的konsole
s don'没有 tty)。
旁注: pid == pgid == 9373 表示 9373 也是一个自称为会话领导者的进程。