fork() 小记
fork
在 UNIX/Linux 中,fork()
用于创建当前进程的子进程
vfork()
在新建子进程后,将父进程阻塞
子进程
fork 出来的子进程,与父进程有着完全一致的变量值和程序计数器。
对于完全一致的变量值,需要指出的是,父进程和子进程拥有完全不同的内存空间;
对于完全一致的程序计数器,这意味着,在 fork 调用之前的父进程中的全部语句,子进程将不会执行
那么问题来了,对于产生子进程的那条 fork 语句,子进程将如何执行呢?
简单来说,子进程仍然会执行这条 fork 语句,但是并不产生新的进程(不妨使用「反证法」,如果继续产生新的子进程,那么这将是一个无限递归的过程,那么内存岂不是爆满了),只会拥有返回值。
返回值
对于一个父进程,fork 的返回值是创建的子进程的进程描述符(process identifier, PID);
对于子进程,返回值是 0;
如果子进程创建失败(由于内存不足等原因),返回值-1。
实例演示
以一段 C 程序为例:
1 |
|
根据进程调度的不同,可能有以下两种输出结果:(当然 pid 也大概率不一致)
1 |
|
观察发现,hello world
只在父进程打印了,而没有在子进程中进行打印
例题
-
在 UNIX 系统下执行以下程序,最多可再产生几个进程?
1
2
3
4
5main() {
fork(); // PC is here
fork();
fork();
}ANS: 7
-
以下程序一种可能的输出(设最开始的进程的 PID 为 1000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "stdio.h"
#include "sys/types.h"
#include "unistd.h"
int main() {
pid_t pid1;
pid_t pid2;
pid1 = fork();
pid2 = fork();
printf("pid1:%d, pid2:%d\n", pid1, pid2);
}
// possible result
pid1:1001, pid2:1002 (1000 进程的输出)
pid1:0, pid2:1003 (1001 进程的输出)
pid1:0, pid2:0 (1003 进程的输出)
pid1:1001, pid2:0 (1002 进程的输出)解析:画出树形图比较方便(Linux 中的进程也是按照树的结构组织的)
此外注意,1003 进程的 pid1 为 0,1002 进程的 pid 为 1001,是从它们各自的父进程复制而来的
Ref:
- Linux Programmer’s Manual:
man fork
man vfork
- 【linux】linux中fork()详解(实例讲解)|fork的运行机制_bandaoyu的博客-CSDN博客_linux fork
fork() 小记
https://exapricity.tech/Fork-Glimpse.html