【Linux】fork函数的理解

fork函数总结

先说下fork函数
这里写图片描述

在Unix/Linux中用fork函数创建一个新的进程。进程是由当前已有进程调用fork函数创建,分叉的进程叫子进程,创建者叫父进程。该函数的特点是调用一次,返回两次,一次是在父进程,一次是在子进程。两次返回的区别是子进程的返回值为0,父进程的返回值是新子进程的ID。子进程与父进程继续并发运行。如果父进程继续创建更多的子进程,子进程之间是兄弟关系,同样子进程也可以创建自己的子进程,这样可以建立起定义关系的进程之间的一种层次关系。

1、子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。父子进程共享代码段,但是分别拥有自己的数据段和堆栈段

现在很多现实并不执行一个父进程数据段,栈和堆的完全复制。而是采用写时复制技术。这些区域有父子进程共享,而且内核将他们的访问权限改变为只读的。如果父子进程中的任一个试图修改这些区域,则内核只为修改区域的那块内存制作一个副本,通常是虚拟存储器系统中的一“页”。

2、一般来说,在fork之后的父进程先执行还是子进程先执行是不确定的。(取决于内核的调度算法)

子进程可以通过getppid函数获得自己父进程的ID,进程可以通过getpid函数获得自己的ID。

3、在linux中存在缓冲区的问题。当写printf函数,但是没有换行的话,它是不会输出的,而是先将要输出的内容存放再缓冲区中,当碰到换行时,将缓冲区中的内容再一起输出。

所以fork后子进程会复制父进程的缓冲区,因此也将待输出内容复制到自己“与父进程独立的缓冲区中”,因此当子进程执行遇到换行,就将缓冲区中的内容全都输出来。

程序1

#include < unistd.h >
#include < stdio.h >

int main(int argc, char *argv[])
{
    int i;
    pid_t pid;
    for(i=0; i<2; i++)
    {
        pid = fork();
        printf("-");
    }
    return 0;
}

先分析有几个进程:4 (丑图,别介意)
这里写图片描述

再分析输出

主进程执行了两次,i=0,i=2,所以输出两个 - -(总计:2个)

first是主进程的子进程,但是i=0时主进程fork 并没有执行printf,所以
缓冲区里面没有东西,first进程执行了两次printf是输出自己的两个 – -。(总计:2个)

second进程是i=1时主进程fork的子进程,此时主进程缓冲区已经有一个-,所以second 拷贝了一个 ,然后再执行一次printf,一共输出两个 - - 。(总计:2个)

third 是first进程的子进程,分析与second一样,输出两个 - -。(总计:2个)

所以一共输出八个 ——-

程序2、

#include < unistd.h >
#include < stdio.h >

int main(int argc, char *argv[])
{
    int i;
    pid_t pid;
    for(i=0; i<2; i++)
    {
        printf("-");
        pid = fork();
    }
    return 0;
}

注意:程序2与程序1不一样,printf在前,fork在后。
同样也是产生4个进程,同样输出八个-。但是原理与程序1不一样。
分析:
主进程与程序1 一样 同样输出两个–。

first进程会输出1个自己的中划线(i=1的时候执行了printf,i=0时没有执行printf,因为fork时从fork执行后开始执行代码 ),还会输出从主进程缓冲区拷贝过来的1个中划线(总计:2个)

second进程没有自己的中划线输出,会输出从主进程缓冲区拷贝过来的2个中划线(总计:2个)

third进程没有自己的中划线输出,会输出从first进程缓冲区拷贝过来的2个中划线 (总计:2个)

程序3

#include < unistd.h >
#include < stdio.h >

int main(int argc, char *argv[])
{
    int i;
    pid_t pid;
    for(i=0; i<2; i++)
    {
        printf("-\n");
        pid = fork();
    }
    return 0;
}

同样是四个进程。
分析:加了换行符,说明不会从缓冲区拷贝
fork执行后,子进程是从该函数之后继续执行代码
主进程:输出两个 - -。
first 进程,输出1个-,i=0时,后面没有代码,i=1时,先执行了printf输出了一个-。
second 是i=1时,主进程创建的子进程,但是此时second执行fork之后的代码,没有printf,所以不会输出。
third 与second 同理。
所以 总共输出3行短杠,一行一个


程序4、

#include < unistd.h >
#include < stdio.h >

int main(int argc, char *argv[])
{
    int i;
    pid_t pid;
    for(i=0; i<2; i++)
    {
        pid = fork();
        printf("-\n");     
    }
    return 0;
}

分析:同样是四个进程。

主进程,输出两行 - -。
first进程,输出两行- -,i=0,i=1分别输出短杠
second 进程,输出一行短杠,i=1时。
third进程,输出一行短杠,i=1,与second同理。
所以一共输出6行短杠。






关于fork函数就先介绍这里,欢迎大家与我交流。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值