#转载#深入理解进程创建函数fork()---一次到多次fork()

今天学习操作系统的时候对于创建子进程的fork()语句理解起来有些困难,搜索之后发现这两篇结合代码分析的博客思路很清晰易懂,特此整合成一篇。仅做学习交流用途!

1.一次fork()

#include<stdio.h>
#include<unistd.h>
int main()
{
    pid_t pid;
    int count = 0;
    pid = fork();   //fork一个进程
    if(pid == 0)
    {               //pid为0,
        printf("this is child process, pid is %d\n",getpid());//getpid返回的是当前进程的PID
        count+=2;
        printf("count = %d\n",count);
    }
    else if(pid > 0)
    {
        printf("this is father process, pid is %d\n",getpid());
        count++;
        printf("count = %d\n",count);
    }
    else
    {
        fprintf(stderr,"ERROR:fork() failed!\n");
    }
    return 0;
}

fork的时候发生什么?

1.执行到这一句的时候,一个子进程被创建了,这个进程与父进程一样,拥有一套与父进程相同的变量,相同的一套代码,这里可以粗浅的理解为子进程又复制了一份main函数。这里返回一个子进程的进程号,大于0。(第一次fork)

2.子进程怎么执行:

子进程从fork()的位置开始执行,也就是说前面的代码不走,但是拥有之前的变量以及变量的值,与父进程的值一样,这次fork(),返回值是0,所以在子进程里面直接执行了pid==0这一个分支,父进程里面并不执行这个分支的语句。这就为我们在写mian函数的时候怎么写子进程的程序提供了一个方法来隔离代码。

2.两次fork():


#include "csapp.h" int main() {

  fork();  //位置1·

  fork();  //位置2

  printf("hello/n");

  exit(0); }

//结果打印出4个hello;

为什么会这样呢?
原来在创建子程序时,子程序会得到父程序的一份拷贝,那么其中也包括下一条指令指针。具体如下:

开始只有一个父进程;

父进程执行完第一个fork()(这时下一条指令指针变成位置2)。
创建出的一个子进程(这个进程也会从位置2开始执行)
所以这个子进程会又创建一子子进程;(这时就有两个子进程了)

父进程再执行第二个fork();
又会创建一个子进程(这时就三个子进程了)
加上父进程一共四个,所以输出4个hello world;

3.三次fork()

明白了这个原理之后我们再来看一段代码

#include<stdio.h>
#include<unistd.h>
int main()
{
    pid_t pid[3];
    int count = 0;
    pid[0] = fork();
    pid[1] = fork();
    pid[2] = fork();

   printf("this is process\n");

   return 0;
}

运行结果
在这里插入图片描述

这里附上思维导图助于理解
在这里插入图片描述

4. 补充

今天上了操作系统课,通过几个例题又有了新的体会:

在这里插入图片描述

这里需要注意一点,对于第一条语句,先执行fork()操作,再进行print。
具体思路如下(进程家族树):

在这里插入图片描述
(红色数字为每个进程打印的次数)

因此,共八个进程(包括main函数),打印14条语句。

在这里插入图片描述

注意:子进程在创建过程中复制了父进程的资源,因此单独的对子进程/父进程的操作对另一方不会造成改变。

因此结果输出为:5

关于父子进程之间的资源共享问题,可以参考下面这篇博文:https://www.cnblogs.com/xuelisheng/p/10072065.html

#END
#update 2020.3.2

发布了3 篇原创文章 · 获赞 3 · 访问量 235

猜你喜欢

转载自blog.csdn.net/weixin_43408412/article/details/104602375