fork函数

系统环境:ubuntu

进程特性:

  • 每一个进程都有一个非负整型的唯一的进程id.
  • 一个进程结束之后,其进程id 不用被新创建进程立即复用,大部分unix系统为采用延迟复用算法

UNIX 中提供获取进程id 和 父进程 id 函数

pid_t getpid (void); // return process id
pid_t getppid (void); // return parent process id

fork函数

pid_t fork(void);

描述

  • 通过复制(duplicate)当前进程创建一个新的进程。子进程同时复制了父进程的数据空间、堆。这样父进程和子进程管理各自的存储空间,并不会共享

  • 程序在执行fork()之后,子进程和父进程继续执行fork()之后的代码。

返回值

  • true,返回父进程创建的子进程id,子进程返回0;< 0 ,创建进程错误。

eg:

这里写图片描述

在这sleep(1000) 主要为了便于使用 ps -axf 命令 查看进程之间关系。

执行结果:

这里写图片描述

左面程序执行结果,右边ps 进程关系图。看出 父进程3241 子进程 3242 ,子进程id生成遵循延迟算法。 有没有想过为啥只有父进程输出了一个Begin ?

这里写图片描述

那么我稍微修改一下代码如下:

这里写图片描述

将标准输出改为文件输出,结果如下:

这里写图片描述

出现了两次Begin ! 为啥呢?

还记着缓冲机制吗?上面这个例子明显是全缓冲,全缓冲只有缓冲区已经满了,或者强制刷新才会输出。缓冲之间差异可参考博客:

http://blog.csdn.net/wning1/article/details/60476480

解决方法:

只需要在第一个Begin 输出语句紧接着加上一句fflush(null)

下面用一个例子说明僵尸进程

僵尸进程: 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程, 因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程, 看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init 来接管他,成为他的父进程……

30000000-30000200 之间寻找素数。

这里写图片描述

结果如下:

这里写图片描述

这里写图片描述

子进程运行完毕变为(Z+),父进程还未运行完毕也没有调用wait()函数,子进程就会在创建它的父进程下面成为僵尸进程。

看另外一种情况,我们把sleep(1000)放到子进程的exit(0) 前面,同时去掉父进程中的sleep(1000)。

结果如下:

这里写图片描述

这个时候父进程早就运行完毕退出了,哈哈,但是子进程还没有运行完咋办,这个时候 1 号进程id接管这个进程,等他们运行完毕,在将他们清除掉。

上面那样肯定是不好的,子进程就相当与父进程的孩子,父进程把他们创建出来了,却不负责清除他们,这怎么能行呢?谁创建谁销毁。

那么我们就可以这样去写:

这里写图片描述

使用一个wait 函数,等待子进程运行完毕,然后将子进程销毁之后,在退出程序!

关于fork() 函数就先说道这….

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值