进程创建(fork和vfork的区别)

关于进程创建,系统提供三个系统调用fork()、vfork()、clone()。

一、fork()

头文件:#include <unistd.h>
函数原型:pid_t fork(void);

fork创建的子进程和父进程共享代码段,复制数据段和堆栈段,复制时是“写时拷贝”技术,即一旦fork成功后,父进程和子进程的地址空间已经分开,两者独立运行,不会相互影响。
当然子进程也不是完全复制父进程,还有少量信息不同,例如:进程的标识、状态等。

fork有两个返回值,子进程返回0,父进程返回子进程的ID。一般来说,fork之后父进程子进程的执行顺序是不确定的,这取决于调度器。一般,父进程通过调用wait或waitpid来等待子进程运行结束后自己再运行。
fork的一大特性是父进程的所有打开文件描述符都被复制到子进程中。父子进程的每个相同的打开描述符共享一个文件偏移量。

父子进程的区别:

1.fork的返回值
2.进程ID
3.具有不同的父进程ID
4.子进程的tms_utime、tms_stime、tms_cutime、tms_ustime均被设置为0
5.父进程设置的文件锁不会被子进程继承
6.子进程的未处理闹钟被清理
7.子进程的未处理信号集被设置为空集

二、vfork()

头文件:#include <unistd.h>
pid_t vfork(void);

vfork和fork都可以创建一个子进程,那么既然都有fork了,为什么还会有vfork?
假设fork创建一个子进程后,产生一个父进程的副本,然后调用一个exec执行一个新的代码段,这样一个程序替换了当前进程的正文、数据、堆栈段,这样的拷贝就觉得无意义了。于是就出现了vfork。

vfork用于创建一个子进程,而该进程的目的是exec一个子进程。vfork不将父进程的地址空间复制到子进程中,因为子进程会立即调用exec,于是不会存放该地址空间。相反,在子进程调用exec和exit之前,它在父进程的空间中运行,即会更改父进程的数据段、栈和堆中运行。

总结:

vfork和fork都会创建一个子进程,但是vfork并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec会exit,不过在子进程调用exec或exit之前,它在父进程的空间运行。

三、fork和vfork

1.fork:子进程拷贝父进程的数据段、代码段
vfork:子进程与父进程共享数据段
2.fork父子进程的执行次序不确定
vfork保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在调用exec或exit后父进程才能被调度运行。
3.vfork保证子进程先执行,在调用exec或exit之后父进程才可能被调度运行,如果在调用这两个函数之前子进程依赖于父进程的进一步动作,会导致死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值