一、认识fork函数
1.含义:在linux中fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程,它没有任何参数。
2.返回值:它有两个返回值,它的返回值是给调用后的父进程返回子进程的pid,如果调用成功,给子进程返回0值,可以理解为当形成一个进程的时候产生一个链表,它一方面可以指向自己,另一方面可以指向下一个结点,但是该结点的下一个结点为空也就是该子进程没有下一个子进程,则返回0.如果该进程创建失败,则返回-1.
思考一下,fork函数为什么会有两个返回值呢?其实从另一个方面理解就是,一本书分别由两个人去看,最后反馈的结果是不一样的,虽然fork中return只返回了一次,但是实际上被执行了两次,所以才有的两个返回值。
3.用法:一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子进程来处理请求。一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。
4.fork调用失败的原因:系统中有太多的进程或者实际用户的进程数超过了限制
二、代码理解
1.当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以开始它们自己的旅程,看如下程序
#include"proc.h"
2 #include"unistd.h"
3 int main()
4 {
W> 5 pid_t ret=fork();
6 printf("hello :pid:%d,ppid: %d,ret: %d\n",getpid(),getppid(),ret);
7 sleep(1);
8 return 0;
9 }
2.如下图为执行过程,该fork函数创建了两个进程,pid含义为自身进程号,ppid为该进程的父进程号,如下可以看出第一个父进程创建后返回了其子进程的pid=28837,创建了子进程返回了0值。
三、如何判断fork创建的是子进程还是父进程
因为如果fork函数返回值有两个一个是父进程pid,一个是0,所以我们可以用if语句来判断它的返回值ret是否大于0来区分是父进程还是子进程。
#include"proc.h"
2 #include"unistd.h"
3 int main()
4 {
5 pid_t ret=fork();
6 if(ret>0)
7 printf("I am parent=%d\n",getpid());
8 else if (ret==0)
9 printf("I am child=%d\n",get pid);
10 else
11 {
12 printf("fork error");
13 }
14 sleep(1);
15 return 0;
16 }
总结:fork函数之后有两个执行流,也就是在同一时刻两个代码块可以同时在子进程和父进程中执行,c语言中是不能实现的,但是系统这一层面是可以实现的。父进程创建子进程的时候,代码是共享的,数据是各自私有一份(写时拷贝),父子进程fork创建完毕的时候,谁先运行是有调度器来决定的。