复刻(英语:fork,又译作派生、分支)是UNIX或类UNIX中的分叉函数,fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。
fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器,在父进程中使用的相同打开文件。
它不需要参数并返回一个整数值。下面是fork()返回的不同值。
- 负值:创建子进程失败。
- 零:返回到新创建的子进程。
- 正值:返回父母或来电者。该值包含新创建的子进程的进程ID。
一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
我们可以通过一个经典案例来熟悉fork机制。 以下代码使用gcc编译
#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", pid1, pid2);
}
例如:gcc -o fork_test fork_test.c生成fork_test后运行。
假设父进程输出的结果是pid1:9268, pid2:9269。那么执行过程中将一共运行几个进程,其他几个进程的输出结果又是如何
根据fork原理(fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本)fork会上程序切分成二部分A.B二个副本,拥有完全一致的资源。
1)当进程A运行到pid1 = fork();时,创建出副本B,此时A进程得到pid1=9268,B进程同步A进程相关资源。pid1=0, pid2=0
- A:pid1=9268, pid2=0
- B:pid1=0, pid2=0
2)当进程A运行到pid2 = fork();时,创建出副本C,此时A进程得到pid2=9269,C进程同步A进程相关资源。pid1=9268, pid2=0
- A:pid1=9268, pid2=9269
- B:pid1=0, pid2=0
- C:pid1=9268, pid2=0
3)当B进程运行到pid2 = fork();时,创建出副本B1,此时B进程得到pid2=9270,B1进程同步B进程相关资源。pid1=0, pid2=0
- A:pid1=9268, pid2=9269
- B:pid1=0, pid2=9270
- C:pid1=9268, pid2=0
- B1:pid1=9268, pid2=0
程序运行结果如下: