深度剖析fork()的原理及用法

Posted disdader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度剖析fork()的原理及用法相关的知识,希望对你有一定的参考价值。

  我们都知道通过fork()系统调用我们可以创建一个和当前进程印象一样的新进程.我们通常将新进程称为子进程,而当前进程称为父进程.而子进程继承了父进程的整个地址空间,其中包括了进程上下文,堆栈地址,内存信息进程控制块(PCB)等.

  1.父子进程

  那么我们首先来先说说父进程和子进程之间的区别:

  • 父进程设置了锁,子进程不继承
  • 进程ID不同
  • 子进程的未决告警被清除
  • 子进程的未决信号集设置为空集

  2.fork系统调用说明

  通过man手册我们可以轻松知道fork()包含的头文件<sys/types.h>和<unistd.h>,功能就是创建一个子进程.函数原型:pid_t fork(void),pid_t是带一个代表经常号pid的数据结构.如果创建成功一个子进程,对于父进程来说是返回子进程的ID.而对于子进程来说就是返回0.而返回-1代表创建子进程失败.

  

  

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <signal.h>

int main(void)
{
    pid_t pid ;
    signal(SIGCHLD,SIG_IGN);
    printf("before fork pid:%d\\n",getpid());
    int abc = 10;      
    pid = fork();          if(pid == -1)   //错误返回
    {
        perror("tile");
        return -1;
    }
    if(pid > 0)     //父进程空间
    {
        abc++;
        printf("parent:pid:%d \\n",getpid());
        printf("abc:%d \\n",abc);
        sleep(20);
    }
    else if(pid == 0){   //子进程空间
        abc++;
        printf("child:%d,parent: %d\\n",getpid(),getppid());
        printf("abc:%d",abc);
    }
    printf("fork after...\\n");
}before fork pid:27319parent:pid:27319 

before fork pid:27319parent:pid:27319
abc:11
before fork pid:27319child:27320,parent: 27319
abc:11fork after...

 

  3.fork()系统调用注意点:

  通过以上程序我们可以知道:1)fork系统调用之后,父进程和子进程交替执行,并且它们处于不同空间中。

2)fork()函数的一次调用返回2次返回,这个有点抽象难理解,此时二个进程处于独立的空间,它们各自执行者自己的东西,不产生冲突,所以返回2次一次pid ==0,一次pid大于0.而至于是先子进程还是父进程先执行,这没有确切的规定,是随机的.

3)将fork()返回值大于零设置为父进程,这是因为子进程获得父进程的pid相对容易,而父进程获子进程pid叫难,所以在在fork()系统调用中将子进程的pid字节有它自己返回给父进程.

4)forl()的子执行过程在fork()之后并不是从头开始,因为在fork()之前,父进程已经为子进程搭建好了运行环境了.所以字节有效代码处开始.理解了上面四点,相信我们应该对此系统调用一定有较深的了解.

  4.vfork()系统调用:

  那么讲完了fork(),我们不妨和vfork()比较,并且学习终结一下vfork(.);vfork()在某些情况下,我们知道vfork()与fork()执行结果是一样的,除了子进程会执行一次exec系统调用或者调用_exit(0)退出.函数原型:pid_t vfork vfork(void),具体返回值与其中fork()类似. 这个函数时是在没有实现写时赋值前提下,所以现在我们并不推荐使用vfork().

  • 结论如下  1)vfork() 子进程与父进程共享数据段

 2)vfork() 中是子进程先执行,父进程后执行.

  通常我们都是与exec函数在一起,在主进程中替换进程印象.

以上是关于深度剖析fork()的原理及用法的主要内容,如果未能解决你的问题,请参考以下文章

深度剖析 VS Code JavaScript Debugger 功能及实现原理

唯一插件化Replugin源码及原理深度剖析--唯一Hook点原理

唯一插件化Replugin源码及原理深度剖析--唯一Hook点原理

唯一插件化Replugin源码及原理深度剖析--插件的安装加载原理

唯一插件化Replugin源码及原理深度剖析--插件的安装加载原理

深度剖析Spark分布式执行原理