进程组、进程组组长、会话的联系 实验
进程组、进程组组长、前后台进程组、会话之间的关系
如图所示:
- 每个进程组中有多个进程,只有一个进程组组长()
- 一个会话(session)中包含许多进程组,只有一个前台进程组。该会话中所有进程的sid都指向该前台进程组的组长进程。
基础概念
自动接受终端信号的组称为前台进程组
在终端通过 ctrl + c 等动作产生的信号首先被前台进程组接受
在 shell 启动的若干个进程组默认是父进程所在的组为前台进程组
除非是默认,否则都要通过调度才能成为前台进程组
随着而来的存在几个问题:
问题1: 前台进程组的组长和是否和会话(session)领头进程存在关系,比如该组的gpid == sid? (前台进程组组长是否等于会话领头进程)
问题2: 结合 孤儿进程实验 为什么当我们关闭远程终端连接之后,该终端创建的所有进程都会被杀死。
问题1
先说答案,前台进程组组长和会话领头进程确实有关,但进程组组长不是
进程组组长
我们可以直接使用ps命令
ps
ps -o pid -o pgid -o ppid -o sid
输出如下
(注意第二次ps的pid和第一次不一样因为它们是不同的进程)
其中ps进程的sid和其pgid并不相等。但是其ppid等于会话进程的pid
原因很简单,虽然这两个进程在同一会话,但是其并不在同一进程组。因此进程组组长和会话领头进程并没有直接关系。
前台进程组组长
接下来,我们创建一个全新的会话,打印一下当前进程的pid、ppid、pgid、sid.
pid_t ret = fork();
if (ret == -1) { return -1; }
if (ret > 0) { exit(0); }
sleep(1);
ret = setsid();
printf("% s(% d) :< % s> pid=%d ppid=%d pgid=%d sid=%d\n", __FILE__, __LINE__, __FUNCTION__, getpid(), getppid(), getpgid(getpid()), getsid(getpid()));
该代码创建了全新的会话,打印了当前会话进程的信息。注意setsid()创建了全新的会话,但是只能在子进程中创建。
该进程成为了全新会话的前台进程组长且。也是成了该会话的会话领头进程,其sid指向了自己。
问题2
我们干过一会儿会儿运维的都知道,关闭远程连接终端一定会导致其子进程被杀掉。但是根据孤儿进程的原理,子进程将会被托管给Init进程。
这是由于会话的机制导致的。
一般来讲除非创建会话,当前会话下创建的所有子进程都属于该会话,包括前台进程组和 后台进程组。当会话关闭后(注意不是会话领头进程死亡),会话下所有进程组将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。但是可以屏蔽,比如使用命令。
nohup command
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现