美文网首页
操作系统fork函数

操作系统fork函数

作者: 王王王王王景 | 来源:发表于2019-08-26 14:55 被阅读0次

1、fork函数简介

参考:https://www.jianshu.com/p/484af1700176

  • 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

  • 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

#include <stdio.h>
#include <unistd.h> // (windows没有unistd.h)
int main()
{
    pid_t fpid;
    int count = 0;
    fpid = fork();
    
    if(fpid < 0) {
        printf("error in fork\n");
    } else if(fpid == 0) {
        // 表示子进程
        printf("son process\n");
        ++count;
    } else {
        // > 0表示父进程
        printf("father process\n");
        ++count;
    }
    printf("fpid = %d , count = %d\n", fpid, count);
    return 0;
}

(macos + xcode)运行结果是:

father process
fpid = 13915 , count = 1
son process
fpid = 0 , count = 1

其实就相当于链表,进程形成了链表,父进程的fpid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其fpid为0.

fork出错可能有两种原因:

  • 当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。

  • 系统内存不足,这时errno的值被设置为ENOMEM。

fork()产生的子进程不是从#include处开始复制代码的,这是因为fork是把进程当前的情况拷贝一份,执行fork时,进程已经执行完了int count=0;fork只拷贝下一个要执行的代码到新的进程。

2、fork进阶知识

#include <unistd.h>  
#include <stdio.h>  
int main(void)  
{  
   int i=0;  
   printf("i son/pa ppid pid  fpid/n");  
   //ppid指当前进程的父进程pid  
   //pid指当前进程的pid,  
   //fpid指fork返回给当前进程的值  
   for(i=0;i<2;i++){  
       pid_t fpid=fork();  
       if(fpid==0)  
           printf("%d child  %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
       else  
           printf("%d parent %4d %4d %4d/n",i,getppid(),getpid(),fpid);  
   }  
   return 0;  
}  

运行结果:

  i son/pa ppid pid  fpid
 0 parent 2043 3224 3225
 0 child  3224 3225    0
 1 parent 2043 3224 3226
 1 parent 3224 3225 3227
 1 child     1 3227    0
 1 child     1 3226    0

这份代码比较有意思,我们来认真分析一下:

  • 由于第二行的输出可以看出来,当前进程的pid是3224,其父进程的pid是2043,在i=0的时候执行fork产生子进程pid=3225,2043-->3224-->3225;

  • 第三行的输出是由pid=3224通过fork产生的子进程pid=3225,每一个子进程的fpid都是0

  • 第四行输出是由于迭代到i=1的时候,当前进程pid=3224的进程第二次执行fork函数产生新的子进程pid=3226, 2043-->3224-->3226; 当输出后pid=3224的进程结束了

  • 第五行输出是由于第一次执行fork函数的时候产生的子进程得到的i=0,还需要执行下一次i=1的操作,因此pid=3225也会产生属于它的子进程,pid=3227,此时pid=3225的子进程相对于pid=3227的进程来说,它自己就是父进程,3224-->3225-->3227; 当输出后pid=3225的进程结束了

  • 第六行的输出是来自于pid=3227的子进程,fpid=0;为啥ppid=1呢?而不是3225,因为3225的进程已经结束了,pid = 1是永远不会死亡的

  • 第七行的输出来自于pid=3226,(由于第二次执行fork产生的子进程),同上ppid=1(3224的进程已经结束了)


相关文章

  • Redis AOF重写的实现原理

    1. 操作系统基础 1.1. fork 当我们在一个程序的函数中调用 fork 函数时,fork 函数会创建一个子...

  • python 杂记

    进程 fork()函数Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用...

  • python学习笔记-tip53(多进程--multiproce

    操作系统背景知识 Unix/Linux系统 Unix/Linux提供了一个fork()函数系统调用,这个fork(...

  • 操作系统fork函数

    1、fork函数简介 参考:https://www.jianshu.com/p/484af1700176 一个进程...

  • 多进程

    fork Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一...

  • fork() 与exec()的区分

    一、fork函数详解 函数原型: #include pid_t fork(void); fork函数是对整个进程进...

  • linux中fork()函数详解 (阅读笔记)

    linux中fork()函数详解(转载) 一、fork入门知识 在Linux中fork函数是非常重要的函数,它的作...

  • 操作系统之 fork() 函数详解

    引用:CSDN jason314 一、fork入门知识 一个进程,包括代码、数据和分配给进程的资源。fork()函...

  • 系统编程:fork()、exec()前用fflush()刷新缓冲

    一、fork函数的使用异常 有一fork函数使用示例如下: 根据fork函数功能,我们可以在控制台上输出以下内容:...

  • Python 进程和线程

    多进程 forkUnix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,...

网友评论

      本文标题:操作系统fork函数

      本文链接:https://www.haomeiwen.com/subject/enmrectx.html