Linux 多进程编程fork

一、关于printf的缓冲区

1、阻塞3秒后,屏幕上才出现hello
在这里插入图片描述
2、屏幕上先看到hello,才看到阻塞的现象
在这里插入图片描述
在这里插入图片描述
在这里,\n的作用和fflush(stdout)的作用一样,都是将缓冲区中的数据显示到屏幕上。三种情况下,需要将缓冲区的数据显示到屏幕上,缓冲区刷新、放满、程序结束。

由于显示到屏幕上需要使用系统调用功能,所以CPU要从用户态切换为内核态,比较浪费时间,而这个缓冲区则可以提高时间利用效率。
在这里插入图片描述

在这里插入图片描述
exit()fflush缓冲区,然后再_exit退出程序。而_exit直接退出程序,以上的代码执行起来就只能看到阻塞的现象,而没有刷新缓冲区,所以屏幕上不会出现hello

二、关于main函数的参数

在这里插入图片描述

三、复制进程 fork

pid_t fork(void);

函数返回类型 pid_t 实质是 int 类型,Linux 内核 2.4.0 版本的定义是:
在这里插入图片描述
fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程,子进程会复制父进程的所有资源,做到和父进程一模一样

在父进程中返回子进程的 pid > 0,在子进程中返回 0,失败返回-1 。而且子进程也是从被fork返回的地方开始执行。

在这里插入图片描述
父子进程都打印变量n的地址
在这里插入图片描述
可以看见父子进程的&n相同,因为这里打印出来的地址是 逻辑地址而不是物理地址

使用getpid()getppid()获取进程id
在这里插入图片描述
在这里插入图片描述

练习一
在这里插入图片描述
在这里插入图片描述
解析: 出生时i=0的进程打印2次,出生时i=1的进程打印1次,总共6次
在这里插入图片描述

练习二

需要考虑缓冲区:
在这里插入图片描述
在这里插入图片描述

中间提示符出现表示最开始执行的那个进程结束了,后面还有数据表示还有子进程没结束

屏幕上总共出现了8次,由于printf是把数据放在了缓冲区,fork的时候 子进程会复制父进程的所有资源,做到和父进程一模一样。当然也包括了缓冲区,所以会屏幕上会多出2个A。

然而上面带有\n的代码会使得进程fork的时候,缓冲区都是空的,所以子进程复制的缓冲区并没有数据,最后屏幕上会少两个A。

练习三
在这里插入图片描述
在这里插入图片描述
解析: 父进程会产生两个进程,子进程1由于||左侧返回父进程的pid>0,所以不再执行||右侧的fork,直接执行printf。子进程2由于是父进程执行||右侧的fork时产生的,所以子进程2直接执行printf。加上父进程打印结果,一共3个A。

关于僵死进程<defunct>
在这里插入图片描述
退出码存放在pcb中,子进程的退出码由父进程获取

当父进程在子进程之前结束的时候,子进程会由另一个进程收养,一般而言是1号进程(即init进程)

可以看到这里是被1310进程收养,而1310进程是1号进程fork的
在这里插入图片描述

使用wait(&exit_code)获取子进程的退出码,如果子进程不结束,父进程将一直阻塞在wait。子进程结束后,内存中的进程实体被回收,wait可以理解为用于处理子进程的pcb的方法
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcoder-9905

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值