Linux 学习笔记(五):fork() 系统调用

一、fork() 介绍

       fork复刻,又译作:派生分支),是 UNIX 或类 UNIX 中的分叉函数。fork 函数将运行着的程序分成 2 个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。

       fork 系统调用用于创建一个新进程,称为子进程。它与进程(称为系统调用 fork 的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行 fork 系统调用之后的下一条指令。子进程和父进程使用相同的 PC(程序计数器)、相同的 CPU 寄存器、在父进程中使用的相同打开文件。

       简单来说,fork 就是一个复制进程的函数。fork 拷贝当前进程的内存,并创建一个新的进程。fork 函数会将整个进程的内存镜像拷贝到新的内存地址(包括代码段、数据段、堆栈以及寄存器内容)。之后,我们就得到了两个拥有完全一样内存的进程。其中调用 fork 函数的进程为父进程,新生成的进程为子进程。父进程和子进程共存,并一起向下执行指令。

【注】fork 之后父进程和子进程到底谁先执行并不确定,取决于操作系统内核所使用的调度算法

二、fork() 返回值

       fork 系统调用在两个进程中都会返回。在父进程中,fork 系统调用会返回子进程的 PID ;而在新创建的子进程中,fork系统调用会返回 0 。所以即使两个进程的内存是完全一样的,还是可以通过 fork 的返回值区分旧进程和新进程。

fork 返回值 含义
负值 创建子进程失败
0 在子进程中
正值 在父进程中,返回值为子进程的 PID
  • 子进程的 PID = 父进程的 PID + 1

【fork应用举例】

pid = fork();

赋值操作是从右向左的,也就是说对于 pid = fork() :先调用 fork ,再把返回值赋给 pid ,所以子进程和父进程都会有 pid 的赋值操作。但是两个进程中 fork 返回值不同,pid 的值也不同,这就有了 fork 函数的双返回值的效果。

三、fork 总结

       ① 通过调用 fork 函数,我们可以在现有进程的基础上创建一个新进程——子进程。子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。

【注】子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间

       ② fork 函数被调用一次但返回两次。两次返回的唯一区别是:子进程中返回 0 值;父进程中返回子进程ID。

       ③ UNIX 将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的 UNIX(Like)系统下,无法确定 fork 之后是子进程先运行还是父进程先运行,这依赖于系统的实现。所以在移植代码的时候不应该对此作出任何的假设。

猜你喜欢

转载自blog.csdn.net/Amentos/article/details/130686284