fork()详解(处理僵尸进程的方法)

<一>: fork()函数用来创建新的进程,它的特点是调用一次返回两次( 在原来的进程中返回新进程的 PID(新进程的 PID 肯定不等于 0), 在新进程中返回为 0.)

函数原型:pid_t fork(void);

pid_t getpid(); 获取当前进程的 pid 值。
pid_t getppid(); 获取当前进程的父进程 pid 值。
fork

    图一

如图一所示 :我们将A 进程, 也就是调用 fork 的进程称之为父进程, 而新的进程(B 进程)称之为子进程。

<二>:fork 的特性: fork 调用生成的新进程与其父进程谁先执行不一定。

<三>:fork的执行过程:

       (1)申请PID

       (2)申请PCB结构

       (3)复制父进程的PCB

       (4)将子进程的运行状态设置为不可执行的

       (5)将子进程中的某些属性清零,某些保留,某些修改

       (6)复制父进程的页(用到了写时拷贝技术)

这里所用到的写时拷贝技术指的是父子进程在初始阶段共享所有的数据(全局、 栈区、 堆区、 代码), 内核会将所有的区域设置为只读。 当父子进程中任意一个进程试图修改其中的数据时, 内核才会将要修改的数据所在的区域(页) 拷贝一份。

写时拷贝技术针对的是: fork 之后, 子进程往往会替换成新的程序, 所以在 fork 的时候就不需要将父进程完全拷贝出来, 当替换新程序时, 直接给子进程重新分配空间即可。
 

<四>:父子进程建数据共享问题:.data   .bss   .text   .heap的数据都不共享 ,但是父子进程之间共享 fork 之前打开的文件描述符, 并且父子进程共用文件读写偏移量。原理如图二所示:

   å¾äº

 

                        图二

所以, 在执行逻辑上, fork 之前打开的文件, 要 close 两次!!


<五>在调用fork()执行后,可能会产生孤儿进程和僵尸进程,让我们一起看看到底什么是孤儿进程和僵尸进城以及怎么解决他们。

孤儿进程: 父进程结束, 子进程依旧存在。 那么子进程就被称为孤儿进程。 系统会将所有的孤儿进程挂载到 init 下。 init 进程的 pid = 1

僵尸进程: 1,进程结束, 但是 PCB 没释放,2,子进程结束, 父进程未结束, 并且父进程未获取子进程的退出状态

处理僵尸进程方法:
1、 结束其父进程。
2、 父进程获取子进程的退出状态: 在父进程中调用wait()函数,但是wait 函数会阻塞运行, 直到第一个子进程退出。

3、在子进程结束时,子进程给父进程发一个信号(告知父进程我已经结束了)父进程接收到信号后在对子进程做处理
————————————————
版权声明:本文为CSDN博主「微微啦啦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41537785/article/details/81157031

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值