目录
三、if,else语句怎么会同时执行?为什么i会有两个不同的值?子进程创建出来之后去哪里了?
一、如何使用fork函数?
在Linux操作系统里,我们可以通过调用fork函数来创建子进程,fork函数是个返回pid_t(其实就是个有符号的int)类型,无参的函数,它可以通过返回两个不同的值来进行区别父子进程
下面是它的一般用法
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t i = fork();
if(i == 0)
{
printf("我是子进程\n“);
printf("子进程:%d 父进程: %d\n",getpid(),getppid());
printf("\n");
}
else if(i > 0)
{
printf("我是父进程\n");
printf("子进程:%d 父进程: %d",getpid(),getppid());
}
else
{
printf("创建失败");
}
return 0;
}
在它返回的两个值里,其中给子进程返回一个0,给父进程返回子进程的pid(在 Linux 或类 Unix 系统中,每个进程都有一个唯一的 PID,它是由操作系统分配的。它是用来唯一标识在操作系统中运行的每个进程的一个数字),如果创建子进程失败,那么就会返回一个-1。
我们思考一下?
- 在c语言中,一个函数最多也只能有一个返回值,而fork函数怎么有两个返回值?
- if,else语句怎么能同时运行呢?
- 为什么i能够接受两个返回值?
- 子进程创建出来之后去哪里了?
- 为什么给父进程返回子进程的PID,子进程返回0?
二、fork函数如何产生两个返回值?
首先,子进程被创建出来之后,会和父进程一起往下执行代码,当一个函数进行到要返回一个值的时候,这个函数它的核心工作肯定是做完了,也就是说,我们的fork函数在返回一个值之前,就已经把我们的子进程给创建好了,实际上fork函数也只有一个返回值。
因为我们已经把子进程创建好了,子进程会和父进程一起往下执行代码,那么在fork函数的内部,
就会在子进程创建好的那一刻,我们的父子进程就开始一起向下执行代码
所以我们的return会被我们的父进程返回一次,子进程返回一次,那么就会返回两个值,fork函数的内部肯定是添加了区分开我们父子进程的代码,从而使父进程返回子进程PID,子进程返回0。
三、if,else语句怎么会同时执行?为什么i会有两个不同的值?子进程创建出来之后去哪里了?
这是因为我们在调用fork函数创建好子进程之后,我们的代码分成了两个不同的执行路径,一个在父进程中,一个在子进程中。所以i在我们看到的好像是同一个,但实际上并不是同一个i。
子进程的代码段、数据段和堆栈段通常会与父进程在内存中的位置相同,但是在物理内存中是独立的。操作系统使用了写时复制(Copy-On-Write,COW)机制来实现这一点。在子进程创建后,当父进程或子进程中的某个进程尝试修改它们的共享数据时,操作系统会将要修改的数据复制到新的物理内存页中,使得父子进程的数据修改不会互相干扰。所以子进程是和父进程先共用空间,到数据不同时在创建。
就是相当于只有发生数据更改时,子进程就会根据需要来创建一块内存来存放与父进程不同的数据。因此,通过 fork()
函数创建的子进程实际上被放置在与父进程相同的虚拟地址空间中,但在物理内存中是独立的。这样可以节省内存空间,同时确保父子进程之间的独立性。
四,为什么给父进程返回子进程的PID,子进程返回0?
调用 fork()
函数创建子进程时,操作系统会复制当前进程(即父进程)的所有信息,并创建一个新的进程(即子进程)。为了在父子进程中标识彼此,fork()
函数在父进程中返回新创建的子进程的 PID(进程标识符),而在子进程中返回 0。这样,通过检查 fork()
的返回值,可以在代码中判断当前是在父进程还是在子进程中执行。