fork和vfork的区别

您所在的位置:网站首页 getpid函数fork fork和vfork的区别

fork和vfork的区别

2023-04-18 13:12| 来源: 网络整理| 查看: 265

参见百度百科API说明:

fork 头文件:

#include

#include

函数原型:

pid_t fork( void);

(pid_t 是一个宏定义,其实质是int 被定义在#include中)

返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

函数说明:

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。

UNIX将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的UNIX (Like)系统下,我们无法确定fork之后是子进程先运行还是父进程先运行,这依赖于系统的实现。所以在移植代码的时候我们不应该对此作出任何的假设。

为什么fork会返回两次?

由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。因此fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。过程如下图

调用fork之后,数据、堆栈有两份,代码仍然为一份但是这个代码段成为两个进程的共享代码段都从fork函数中返回,箭头表示各自的执行处。当父子进程有一个想要修改数据或者堆栈时,两个进程真正分裂。

fork函数的特点概括起来就是“调用一次,返回两次”,在父进程中调用一次,在父进程和子进程中各返回一次。

fork的另一个特性是所有由父进程打开的描述符都被复制到子进程中。父、子进程中相同编号的文件描述符在内核中指向同一个file结构体,也就是说,file结构体的引用计数要增加。

vfork

vfork(建立一个新的进程)

相关函数wait,execve

头文件 #include

定义函数pid_t vfork(void);

vfork()会产生一个新的子进程.但是vfork创建的子进程与父进程共享数据段,而且由vfork创建的

子进程将先于父进程运行.fork()的使用详见百度词条fork().

vfork()用法与fork()相似.但是也有区别,具体区别归结为以下3点:

1. fork():子进程拷贝父进程的数据段,代码段. vfork():子进程与父进程共享数据段.

2. fork():父子进程的执行次序不确定.

vfork():保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec

或exit之后父进程才可能被调度运行。

3. vfork()保证子进程先运行,在她调用exec或exit之后父进程才可能被调度运行。如果在

调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

4.当需要改变共享数据段中变量的值,则拷贝父进程。

个人理解: fork和vfork都可以用来创建子进程.fork创建子进程后,父子进程的数据段和堆栈段分离,会产生复制消耗资源.而在实际的应用中,有时是不需要的.比如子进程创建后就执行exec调用了.这样就产生了vfork,其产生的子进程和父进程共享数据段. 同时fork创建的子进程和父进程的运行的先后顺序是没有保证的,即可能父进程先运行,也可能子进程先运行.而vfork的特点是保证子进程先运行.只有子进程通过通过exec或者exit退出后,父进程才能运行.但这个特定也决定了,如果子进程依赖父进程的操作的话,就会产生死锁(即其需要父进程执行,而父进程必须在其完成后才能执行,互相等待)。 使用实例

下面通过几个例子加以说明: 第一:子进程拷贝父进程的代码段的例子:

1: #include 2: #include 3: #include 4:  5: int main() 6: { 7: pid_t pid; 8: pid = fork(); 9: if(pid


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3