C语言中的fork()

fork()是用来创建子进程的。
fork()通过复制调用该函数的进程来创建一个新的进程。被fork()出来的进程叫做 child process,而调用fork()函数的进程就叫做 parent process。

先来看一个例子:

#include <unistd.h>  
#include <stdio.h>  
  
int main() {  
    pid_t pid = fork();  
    printf("PID=%d\n", getpid());  
    sleep(30);  
}  

运行一下,输出的结果是:

youon@localhost:~/projects/C> ./a.out   
PID=4040  
PID=4041  

欸等等,代码中明明只有一个printf(),为什么会打印两行字?
这叫做“复制调用该函数的进程来创建一个新的进程”。parent process 在执行fork()之后,被复制出来的 child process 与 parent process 拥有同样的代码,所以就会输出了两个PID。
我们也可以使用 pstree -p <Parent process's PID> 来看看它的进程树:

youon@localhost:~/projects/C> pstree -p 4040  
a.out(4040)───a.out(4041)  

不够形象?我们可以多创建几个进程来看看。

int main() {  
    pid_t pid1 = fork(); //断点1  
    pid_t pid2 = fork(); //断点2  
    printf("PID=%d\n", getpid());  
    sleep(30);  
}  

运行一下,然后使用pstree指令看一下进程树:

youon@localhost:~> pstree -p 4109  
a.out(4109)─┬─a.out(4110)───a.out(4112)  
            └─a.out(4111)  

PID=4109的进程运行到断点1处的时候,创建了PID=4110这个进程;运行到断点2的时候,创建了PID=4111这个进程。
因为fork()“复制调用该函数的进程来创建一个新的进程”,被复制出来的进程(PID=4110)拥有它被复制出来的那一行之后的代码,也就是断点1(不含断点1)之后的代码。所以可以从进程树中看出来,PID=4110创建了一个PID=4112的 child process。