Linux - process IDs, parent process IDs, process group IDs and session IDs 之间的关系

实验环境

Kernel Version: 4.15.0-109-generic
Operating System: Ubuntu 18.04.5 LTS
OSType: linux
Architecture: x86_64
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

概述

Before looking at the Linux implementation, first a general Unix description of threads, processes, process groups and sessions.
A session contains a number of process groups,
and a process group contains a number of processes,
and a process contains a number of threads.
A session can have a controlling tty. At most one process group in a session can be a foreground process group. An interrupt character typed on a tty (“Teletype”, i.e., terminal) causes a signal to be sent to all members of the foreground process group in the session (if any) that has that tty as controlling tty.
All these objects have numbers, and we have thread IDs, process IDs, process group IDs and session IDs.
在这里插入图片描述

实践步骤

root 用户 ssh 远程登陆服务器

root@aliyun:c-code# echo $$
26285

这其实就是一个 session。和 HTTP session 很类似,只不过使用的通信协议不一样。登陆的 login shell,执行的第一个程序就是 bash,这个 bash 进程可以称之为 login process

运行代码

  1. 准备代码,relationship.c
#include <sys/types.h>
#include <unistd.h>
int main(){
        fork();
        while(1);
}

  1. gcc -o relationship relationship.c
  2. ./relationship &
  3. ./relationship &
  4. ./relationship &

检测关系

pstree 查看进程间关系(已删除无关进程)
systemd(1)─├─sshd(2306)───sshd(26249)───bash(26285)─┬─pstree(4464)
           │                                        ├─relationship(26817)───relationship(26818) #终端执行的 relationship
           │                                        ├─relationship(26852)───relationship(26853) #终端执行的 relationship
           │                                        └─relationship(26882)───relationship(26883) #终端执行的 relationship

pidof relationship 查看
# 所有relationship 进程的 id
root@aliyun:c-code# pidof relationship
26883 26882 26853 26852 26818 26817

查看当前 terminal 的 pid
root@aliyun:c-code# echo $$
26285
root@aliyun:c-code# ps -C bash o pid,ppid,pgid,sid,comm
  PID  PPID  PGID   SID COMMAND
  577     1   577   577 bash
22878 20823 22878 22878 bash
26285 26249 26285 26285 bash  # 当前使用终端的 bash pid 是 26285

当前使用终端的 bash pid 是 26285, ppid = 26249 是 sshdpid
pgid = pid = 26285,因为

查看 process IDs, parent process IDs, process group IDs and session IDs 之间的关系
root@aliyun:c-code# ps -C relationship o pid,ppid,pgid,sid,comm
  PID  PPID  PGID   SID COMMAND
26817 26285 26817 26285 relationship #1
26818 26817 26817 26285 relationship #2
26852 26285 26852 26285 relationship #3
26853 26852 26852 26285 relationship #4
26882 26285 26882 26285 relationship #5
26883 26882 26882 26285 relationship #6

分析
SID 分析

可以看到 #1 到 #6 的 SID 都是26285(echo $$), 这是当前 Terminal 的 bash 进程的 ID。
为啥呢?因为 ssh 登陆后,执行的第一个程序就是 bash。根据约定,Session ID = Session 中执行的第一个程序的进程 ID,也就是 Session ID = First PID of this Session = echo $$ = 26285。

Every process group is in a unique session. (When the process is created, it becomes a member of the session of its parent.)
By convention, the session ID of a session equals the process ID of the first member of the session, called the session leader. A process finds the ID of its session using the system call getsid().

Every session may have a controlling tty, that then also is called the controlling tty of each of its member processes.
A file descriptor for the controlling tty is obtained by opening /dev/tty. (And when that fails, there was no controlling tty.) Given a file descriptor for the controlling tty, one may obtain the SID using tcgetsid(fd).

A session is often set up by a login process. The terminal on which one is logged in then becomes the controlling tty of the session. All processes that are descendants(后代) of the login process will in general be members of the session.

PGID 分析

可以看到
#1 和 #2 PGID = 26817
#3 和 #4 PGID = 26852
#5 和 #6 PGID = 26882
一共有 3 个不同的 PGID 。
为啥呢? 首先测试程序 relationship 执行后,会 fork 出一个子进程。
一共执行了 3 次 ./relationship & ,生成了 3 个不同的 PGID,一共有 6 个 relationship 进程。
为啥呢?

Every process is member of a unique process group, identified by its process group ID. (When the process is created, it becomes a member of the process group of its parent.)

每个进程都是由 PGID 唯一区分的进程组的一个成员,当一个进程被创建,这个进程成为它父进程所在进程组的一员。问题来了,父进程所在进程组的 PGID 是怎样确定的呢?

By convention, the process group ID of a process group equals the process ID of the first member of the process group, called the process group leader.

根据约定,PGID = 进程组中第一个进程的 PID。

对于#1 来说,执行 ./relationship & 是该进程组中第一个进程。这个进程就是这个进程组的 leader,可以视为小组长。
所以这个进程组的 PGID = first PID = 26817。
对于 #2 来说,是执行 ./relationship &,fork 出来的进程,和#1 同属一个进程组。

A process finds the ID of its process group using the system call getpgrp(), or, equivalently, getpgid(0).
One finds the process group ID of process p using getpgid§.

图解分析

在这里插入图片描述

有 pid 还不够吗?为啥还有 ppid,pgid,sid

个人理解,为了管理大量的进程。必须对大量的进程进行组织,况且,有的进程间的确有依赖关系。Linux 上默认最多有 32768 个 pid。可以根据需要配置更大的值。以 session、process group、process 三级来组织进程,可以方便组织管理。可以类比一下,始皇帝灭掉六国后,面对超大规模的国土面积,怎样统治呢?始皇帝还专门开御前会议讨论一下,废封建,立郡县。这其实也是在划分。

root@aliyun:~# cat /proc/sys/kernel/pid_max 
32768

References

  1. Process group
  2. 宋宝华: 一图理解终端、会话、 进程组、进程关系
  3. maximum value of pid
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值