vfork和fork区别

fork:

一个现有进程可以调用fork创建一个新进程。

返回值:子进程中返回0,父进程返回子进程ID,出错返回零。

子进程是父进程的副本。

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

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

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

为什么fork会返回两次?

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

在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

父进程的fork函数返回的值指向子进程的进程id, 因为子进程没有子进程,所以其fork函数返回的值为0.

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

fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中。父子进程的每个相同的打开描述符共享一个文件表项。

在fork之后处理的文件描述符有两种常见的情况:

1.父进程等待子进程完成。在这种情况下,父进程无需对其描述符做任何处理。当子进程终止后,子进程对文件偏移量的修改已执行的更新。

2. 父子进程各自执行不同的程序段。这种情况下,在fork之后,父字进程各自关闭他们不需要使用的文件描述符,这样就不会干扰对方使件描用文件述符。 这种方法在网络服务进程中经常使用。

父子进程之间的区别:

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

fork调用失败的原因:

1. 系统中有太多的进程

2. 实际用户的进程数超过了限制

vfork函数

vfork用于创建一个新进程,而该新进程的目的是exec一个新程序。 vfork与fork都创建一个子进程,但它不将父进程的地址空间复制到子进程中,因为子进程会立即调用exec,于是不会存访问该地址空间。相反,在子进程调用exec或exit之前,它在父进程的空间中运行,也就是说会更改父进程的数据段、栈和堆。vfork和fork另一区别在于: vfork保证子进程先运行,在它调用exec或( exit)之后父进程才可能被调度运行。

时间: 2024-11-05 20:39:33

vfork和fork区别的相关文章

vfork与fork(转载)

最近学了一些关于Unix/Linux下C编程的知识,大致了解了关于基于文件描述符的IO.基于流的IO.进程.进程间通信.信号.网络编程.gtk+编程,等等,以及其对应的相关API,看完后觉得也就这样,甚至有些傲慢,这些平日听起来高深的技术也就这些东西,但同时也感到疑惑:怎么可能,绝对不是我第一印象感觉的那样,绝对还有很多我不知道的. 幸好当天晚上没事逛了陈皓的coolshell,看到了一篇文章<vfork 挂掉的一个问题>,才感觉到自己的第一感觉是多么的无知,并不是它简单,而是因为难的.复杂的

如何正确地使用vfork():简析vfork()与fork()的不同

今天看到知乎上有人问了一个由于不恰当的使用vfork()而导致的一个奇怪现象,底下的回答非常精彩.趁此机会我也仔细了解了一下vfork()的特性. 其实对vfork()最完备.权威的表述莫过于man手册里面的解释了. 简单的说,vfork()跟fork()类似,都是创建一个子进程,这两个函数的的返回值也具有相同的含义.但是vfork()创建的子进程基本上只能做一件事,那就是立即调用_exit()函数或者exec函数族成员,调用任何其它函数(包括exit()).修改任何数据(除了保存vfork()

进程使用的总结

当一个知识点,长时间不用的话,那么就会很容易的遗忘,这是一个很正常的规律.所以学而时习之,对我们非常有必要. 那么,这边文章就是对以前学习的进程进行复习和回顾的作用. 我们很容易的知道进程就是程序的一次执行过程,每个进程创建的时候有独立的4GB的空间,有自己的代码段,数据段,堆栈等资源. linux系统下主要包括下面几种进程: 交互式进程,批处理进程,守护进程 一 .运行进程需要那些资源 ?   CPU资源 ,内存资源,时间片资源 二 .进程与程序  程序:一个存放在磁盘上的可执行文件 进程:是

clone(),fork()与vfork()的区别

Linux提供三种方式复制子进程:fork(),clone(),vfork(). 区别: fork()函数复制时将父进程的所以资源都通过复制数据结构进行了复制,然后传递给子进程,所以fork()函数不带参数: clone()函数则是将部分父进程的资源的数据结构进行复制,复制哪些资源是可选择的,这个可以通过参数设定,所以clone()函数带参数,没有复制的资源可以通过指针共享给子进程.Clone()函数的声明如下: int clone(int(*fn)(void *), void *child_s

Linux之fork与vfork区别

创建一个新进程的方法只有由某个已存在的进程调用fork()或vfork() 1.fork()函数 返回值:成功:父进程:返回子进程的PID 子进程:返回0 失败:父进程返回-1 子进程是父进程的一个拷贝.即子进程从父进程得到数据段和堆.栈段的拷贝,这些需要分配新的内存(不是与父进程共享,而是单独分配内存):而对于只读的代码段,通常使用共享内存的方式访问. fork返回后,子进程和父进程都从调用fork函数的下一条语句开始执行. 由于子进程与父进程的运行是无关的,所以,父进程可先于子进程运行,子进

fork与vfork的区别

fork()与vfock()都是创建一个进程,那他们有什么区别呢?总结有以下三点区别: 1.  fork  ():子进程拷贝父进程的数据段,代码段     vfork ( ):子进程与父进程共享数据段 2.  fork ()父子进程的执行次序不确定     vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec     或exit 之后父进程才可能被调度运行. 3.  vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被

fork与vfork的用法与区别

fork和vfork都用于创建进程 fork函数的作用是复制一个进程,当一个进程调用它,完成后就出现两个几乎一模一样的进程,也由此得到一个新的进程,称为子进程.原来的进程称为父进程.子进程是父进程的一个拷贝,即子进程从父进程得到了数据段和堆栈段的拷贝,这些需要分配新的内存:而对于只读的代码段,通常使用共享内存的方式访问. #include<stdio.h> #include<sys/types.h> #include<stdio.h> int main() {     

Linux中fork,vfork和clone详解(区别与联系)

fork,vfork,clone Unix标准的复制进程的系统调用时fork(即分叉),但是Linux,BSD等操作系统并不止实现这一个,确切的说linux实现了三个,fork,vfork,clone(确切说vfork创造出来的是轻量级进程,也叫线程,是共享资源的进程) 系统调用 描述 fork fork创造的子进程是父进程的完整副本,复制了父亲进程的资源,包括内存的内容task_struct内容 vfork vfork创建的子进程与父进程共享数据段,而且由vfork()创建的子进程将先于父进程

UNIX高级环境编程(9)进程控制(Process Control)- fork,vfork,僵尸进程,wait和waitpid

本章包含内容有: 创建新进程 程序执行(program execution) 进程终止(process termination) 进程的各种ID ? 1 进程标识符(Process Identifiers) 每个进程都有一个唯一的标识符,进程ID(process ID). 进程的ID是可重用的,如果一个进程被终止,那么它的进程ID会被系统回收,但是会延迟使用,防止该进程ID标识的新进程被误认为是以前的进程. 三个特殊ID的进程: Process ID 0:调度者进程,内核进程. Process