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。