实验环境
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.
Asession
contains a number of process groups,
and aprocess group
contains a number of processes,
and aprocess
contains a number ofthreads
.
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
运行代码
- 准备代码,relationship.c
#include <sys/types.h>
#include <unistd.h>
int main(){
fork();
while(1);
}
- gcc -o relationship relationship.c
- ./relationship &
- ./relationship &
- ./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 是sshd
的pid
。
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 aunique
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 thefirst member
of the session, called thesession leader
. A process finds the ID of its session using thesystem call getsid
().
Every session may have a
controlling tty
, that then also is called the controlling tty of each of its member processes.
Afile 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 thecontrolling tty of the session
. All processes that aredescendants(后代)
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 iscreated
, it becomes a member of the process group of its parent.)
每个进程都是由 PGID 唯一区分
的进程组的一个成员,当一个进程被创建,这个进程成为它父进程所在进程组
的一员。问题来了,父进程所在进程组的 PGID 是怎样确定的呢?
By convention
, the process group ID of a process groupequals
theprocess ID
of thefirst member of the process group
, called theprocess 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