Fork函数解析

父进程通过调用fork函数创建一个新的运行的子进程,子进程得到与父进程用户级虚拟地址空间相同但是独立的一个副本,他们最大的区别在于它们有不同的PID。

fork函数只被调用一次,但是返回两次:①在新创建的子进程中,fork返回0。②在调用进程中(父进程),fork返回子进程的PID,因为子进程的PID总是不为0,所以通过返回值就能判断程序当前是在父进程还是子进程。

我们通过一些题目来进一步了解fork函数。
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂

在这里插入图片描述

在这里插入图片描述在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂

在这里插入图片描述
在这里插入图片描述
这里理论上可以有多个输出答案:

x=4
x=3
x=2

x=4
x =2
x=3
这是因为父进程和子进程是并发独立进程,内核能够以任何方式交替执行他们的逻辑控制流中的指令。子进程和父进程哪个先执行都是相对随机的。我们可以用wait或者sleep函数来干预它们的执行顺序,让进程暂时等待或者休眠。
在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂

在这里插入图片描述
在这里插入图片描述
atexit函数是一个特殊的函数(注册函数),它是在正常程序退出时调用的函数。
当main中调用exit函数的时候会清除并刷新标准输出缓冲区中的内容。当执行到exit(0)时,exit会自动调用已注册过的函数,但是由于压栈过程中先进后出的原则,所以先注册的函数最后执行。如果一个函数被atexit()登记多次也会被exit()调用多次。
更多关于atexit函数的解析可以看看这位博主的:https://blog.csdn.net/wy1550365215/article/details/70216750

在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂
5.
在这里插入图片描述
在这里插入图片描述
因为父进程有道走到了死循环,所以这个程序将会一直运行,你可以Ctrl+c强行终止或者Ctrl+z将其挂起在后台运行。
在这里插入图片描述若是死循环是放在子进程里面:
在这里插入图片描述
这次的输出有shell指令,而刚才的没有。这是因为父进程是shell main创建的,上面父进程进入死循环,所以不会出现shell命令行,而这里是子进程死循环,父进程并没有,所以会出现shell命令行。

在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂
6.
一个进程可以通过调用waitpid()函数来等待它的子进程终止或者停止。使用时需要添加头文件
#include<sys/wait.h>,函数原型如下:
pid_t waitpid(pid_t pid,int *statusp,int options);
默认情况下options=0,waitpid挂起调用进程的执行,直到他的等待集合中的一个子进程终止。
pid决定等待集合的成员:①pid>0,等待集合是一个 单独的子进程,他的进程ID等于pid②pid=-1,等待集合就是由父进程的所有子进程组成。

wait函数是waitpid函数的简化版本,调用wait(&status)等价于调用waitpid(-1,&statusp,0)。所以如果在父进程中遇到wait,一定会执行完子进程之后(如果有子进程的话)才会执行wait之后的语句。

在这里插入图片描述在这里插入图片描述
✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂✂
7.
换行符\n能够将输出行冲区里的数据并刷新缓冲区。而fork函数创建子进程时,子进程能够得到父进程的代码和数据段、堆、共享库以及用户栈,把缓冲区里的数据也复制到子进程里。所以一个printf里带不带’\n’对输出结果是有影响的。
在这里插入图片描述
因为缓冲区的存在,输出的是8颗星而不是6颗星
在这里插入图片描述
为了更加直观,我们改一下程序:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当我们在printf中加入\n或者ffush(stdout)时,因为会清空缓冲区,所以将会变回6星
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值