一、fork函数详解
函数原型:
#include <unistd.h>
pid_t fork(void);
fork函数是对整个进程进行了复制,我们称新的进程是原进程的子进程,子进程与父进程的区别在于:
1、父进程设置的锁,子进程不继承(因为如果是排它锁,被继承的话,矛盾了)
2、各自的进程ID和父进程ID不同
3、子进程的未决告警被清除;
4、子进程的未决信号集设置为空集。
二、 exec() 函数详解
用一个新的程序来替换现在的整个进程,其会将程序整个加载到现在的进程中,然后从头开始运行。
三、二者区别
通过上面的描述我们可以知道fork和exec经常会放到一块去使用,来创建一个新的子进程,并且在这个子进程里去运行一个新的程序。fork用来创建子进程,处理的对象是进程;而exec()是用来处理程序,重新加载一个进程里的程序。有人问,问什么不能把这两个东西合成一个syscall呢? 例如windows下就有createprocess的指令。有以下几方面的原因:
1、接口的通用性
要知道二者不一定必须要合在一起使用的,存在这种情况,即当前进程的程序已经执行完成,我可以直接通过exec来加载新程序,并不需要fork出一个新的进程,fork因为是完全复制进程,是很浪费时间的。还有进程监听TCP端口的时候,我们需要生成子进程来处理一些特定需求,然后主进程继续监听,但是这个时候是不需要exec的。
2、效率
fork出一整个进程会占用很多空间(需要存贮进程的指令,数据,栈),将两个syscall 分开可以让我们在子进程执行制定程序前对其进行修改,会高效很多。
还有一点,如果create process的话,就要涉及从一个地址空间把所有数据拿出来然后修改,然后迁移,跨地址空间的修改会很费时;两个分别的是先复制,然后根据exec来做reload。
fork图
网友评论