【Linux】进程间的关系(第十三篇)
目录
1.亲缘关系:
2.进程组关系:
3.会话关系
4.进程、进程组与会话的关系
5.例子
1.亲缘关系:
2.进程组关系:
3.进程间会话关系
1.亲缘关系:
多个进程间可能存在亲缘关系(多个进程间可能是父子进程结构,也可能更为复杂的层级亲缘结构)
2.进程组关系:
- 定义:进程组是一个或多个进程的集合。每个进程除了有一个进程ID(PID)之外,还属于一个进程组。每个进程组有一个唯一的进程组ID(PGID)。
- 组长进程:每个进程组都可以有一个组长进程,其标识是进程组ID等于其进程ID。组长进程可以创建一个进程组,并在其中创建其他进程。重要的是,只要进程组中有一个进程存在,该进程组就继续存在,这与组长进程是否终止无关。
- 作用:进程组通常与作业相关联,可以接收来自同一终端的各种信号。
示例:略(一父多子)
pid_t pid;
for(int i =0; i<3;i++){
pid = fork();
if(pid ==0){
break;
}
}
if(pid >0){
printf("parent process %d\n,group id %d\n",getpid(),getpgrp());
// while(1)sleep(1);
}else if(pid ==0){
printf("child process %d,group id %d\n",getpid(),getpgrp());
// setpgid(getpid(),setpgrp());
//父亲死后,
printf("setpgid child process %d,group id %d\n",getpid(),getpgrp());
while(1)sleep(1);
}
ps ajx 查看进程关系 ps aux 查看进程信息:
进程组关系与亲缘关系没有必然联系,组成员可能构成复杂,频繁变动 创建进程组,转移组中进程,获取PGID setpgid(pid_t pid,pid_t pgid) 转移进程,将pid的进程转到pgid的组,转移的组必须存在 (注意:创建进程组,使用pid 申请pgid,传参时两个参数相等) 父进程默认为进程组组长,无法使用setpgid进行组创建,子进程和非组长进程可以
示例:略(子进程申请进程组)
getpgrp()
无论进程组如何变动,亲缘关系始终保持不变,父进程一定要对子进程进行回收操作(无论子进程组情况如何复杂)
3.会话关系
- 定义:会话是一个或多个进程组的集合。一个会话有一个控制终端,这通常是登录到其上的终端设备或伪终端设备。
- 控制进程:建立与控制终端连接的会话首进程被称为控制进程。一个会话中的进程组可被分为一个前台进程组以及一个或多个后台进程组。
- 作用:会话的意义在于将多个工作囊括在一个终端,并且取其中的一个工作作为前台,来直接接受该终端的输入输出以及终端信号。其他的工作在后台运行。
pid_t pid = fork();
if(pid ==0){
pid_t sid = setsid();
printf("sid %d\n",sid);
printf("child process %d ,group id %d,session %d\n",getpid(),getpgrp(),getsid(0));
while(1)sleep(1);
}else if(pid >0){
printf("parent process %d,session %d\n",getpid(),getsid(0));
while(1)sleep(1);
}
4.进程、进程组与会话的关系
- 一个进程可以属于一个进程组,而一个进程组又可以属于一个会话。这种层级关系使得系统能够更好地管理和控制进程的执行。
- 进程组是系统分配资源或发送信号给一组进程的基础,而会话则是对这些进程组的更高层次的抽象和组织。
5.例子
- 当用户通过终端登录系统时,系统会为该用户启动一个Shell进程,并为其分配一个会话和一个控制终端。这个Shell进程就是这个会话的控制进程,也是前台进程组的组长进程。
- 用户可以在Shell中启动多个进程,这些进程默认属于Shell所在的进程组和会话。用户可以使用Shell的命令(如
&
、fg
、bg
等)来控制这些进程的运行状态,如将进程放到后台运行或将其提到前台运行。 - 如果一个进程组的组长进程退出了,但该进程组中的其他进程还在运行,那么这个进程组依然存在,并由init进程(PID为1的进程)接管。
综上所述,进程间的关系是通过进程组、会话等概念来组织和管理的。这种层级关系使得系统能够更有效地管理和控制进程的执行,同时也提高了系统的灵活性和可扩展性。