本章话题主要关注进程间关系。比如有关进程组、进程组组长、会话、前台进程组等这些概念。设计进程扇和进程链的概念,是为了方便描述进程间关系以及完成相关的实验。
1. 进程扇
如果有一个进程,它生成了若干个进程,这若干个进程之间都是兄弟进程,就把这种关系称为进程扇结构,这一系列进程就是一个进程扇。如图 1 所示。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CM0gDOykzYmR2YidjYzgDMzYzX5EDOxETM2IzLchDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
图1 进程扇
1.1 进程扇构造代码
// ps_swing.c
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int pid, i = 4;
while(i--) {
pid = fork();
if (pid == 0) {
// 如果是子进程,就不能继续循环了。
// 按照进程扇的定义,子进程是没有子进程的。
break;
}
else if (pid < 0) {
perror("fork");
return -1;
}
}
printf("pid: %d -> ppid: %d\n", getpid(), getppid());
while(1) sleep(1);
return 0;
}
1.2 编译与运行
- 编译与运行
$ gcc ps_swing.c -o ps_swing
$ ./ps_swing
- 运行结果
图2 进程扇的构造
- 使用
命令查看进程间关系pstree -ap
图3 查看进程间关系
从图 3 可以看出 ps_swing 这几个进程符合进程扇的定义。
2. 进程链
如果某个进程生成了一个子进程,它的子进程又生成了一个子进程,直到最后一个子进程不再产生新的子进程,那么这一系列进程被称为进程链。如图 4 所示。
图4 进程链
2.1 进程链构造代码
// ps_link.c
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int pid, i = 4;
while(i--) {
pid = fork();
if (pid > 0) {
// 如果是父进程,产生了子进程后就必须退出循环。
// 因为按照进程链定义,一个父进程只能产生一个子进程。
break;
}
else if (pid < 0) {
perror("fork");
return -1;
}
}
printf("pid: %d -> ppid: %d\n", getpid(), getppid());
while(1) sleep(1);
return 0;
}
2.2 编译与运行
- 编译与运行
$ gcc ps_link.c -o ps_link
$ ./ps_link
- 运行结果
图5 进程链的构造
- 使用
命令查看进程间关系pstree -ap
图6 查看进程间关系
3. 总结
- 掌握进程扇和进程链的基本概念
- 掌握进程扇和进程链的构造方法