当前位置: 技术问答>linux和unix
what's the difference between fork()&vfork()?
来源: 互联网 发布时间:2015-04-22
本文导语: i am new user,please give directions,thanks! | 因为‘fork()’包括拷贝整个进程的地址空间,所以非常“昂贵”,这个‘vfork()’函数因此被引入.两者的基本区别在于当使用‘vfork()’创建新进程时,...
i am new user,please give directions,thanks!
|
因为‘fork()’包括拷贝整个进程的地址空间,所以非常“昂贵”,这个‘vfork()’函数因此被引入.两者的基本区别在于当使用‘vfork()’创建新进程时,父进程将被暂时阻塞,而子进程则可以借用父进程的地址空间。这个奇特状态将持续直到子进程要么退出,要么调用ecve()’,至此父进程才继续执行。这意味着一个由‘vfork()’创建的子进程必须小心以免出乎改变父进程的变量。特别的,子进程必须不从包含‘vfork()’调用的函数返回,而且必须不调用‘exit()’(如果它需要退出,它需要使用‘_exit()’;事实上,对于使用正常‘fork()’创建的子进程这也是正确的)
|
‘exit()’与‘_exit()’的基本区别在于前一个调用实施与调用库里用户状态结构(user-mode constructs)有关的清除工作(clean-up),而且调用用户自定义的清除程序(自定义清除程序由atexit函数定义,可定义多次,并以倒序执行),相对应,后一个函数只为进程实施内核清除工作。
在由‘fork()’创建的子进程分支里,正常情况下使用‘exit()’是不正确的,这是因为使用它会导致标准输入输出(Standard Input Output)的缓冲区被清空两次,而且临时文件被出乎意料的删除(临时文件由tmpfile函数创建在系统临时目录下,文件名由系统随机生成)。在C++程序中情况会更糟,因为静态目标(static objects)的析构函数(destructors)可以被错误地执行。(还有一些特殊情况,比如守护程序,它们的父进程需要调用‘_exit()’而不是子进程;适用于绝大多数情况的基本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。)在由‘vfork()’创建的子进程分支里,‘exit()’的使用将更加危险,因为它将影响
父进程的状态。
在由‘fork()’创建的子进程分支里,正常情况下使用‘exit()’是不正确的,这是因为使用它会导致标准输入输出(Standard Input Output)的缓冲区被清空两次,而且临时文件被出乎意料的删除(临时文件由tmpfile函数创建在系统临时目录下,文件名由系统随机生成)。在C++程序中情况会更糟,因为静态目标(static objects)的析构函数(destructors)可以被错误地执行。(还有一些特殊情况,比如守护程序,它们的父进程需要调用‘_exit()’而不是子进程;适用于绝大多数情况的基本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。)在由‘vfork()’创建的子进程分支里,‘exit()’的使用将更加危险,因为它将影响
父进程的状态。
|
v f o r k函数的调用序列和返回值与f o r k相同,但两者的语义不同。
v f o r k起源于较早的4 B S D虚存版本。在L e ffler 等〔1 9 8 9〕的5 . 7节中指出:“虽
然它是特别有效率的,但是v f o r k的语义很奇特,通常认为它具有结构上的缺陷。”
尽管如此S V R 4和4 . 3 + B S D仍支持v f o r k。
某些系统具有头文件,当调用v f o r k时,应当包括该头文件。
v f o r k用于创建一个新进程,而该新进程的目的是e x e c一个新程序(如上节(2) 中一样)。程
序1 - 5中的s h e l l基本部分就是这种类型程序的一个例子。v f o r k与f o r k一样都创建一个子进程,
但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用e x e c (或e x i t ),于
是也就不会存访该地址空间。不过在子进程调用e x e c或e x i t之前,它在父进程的空间中运行。
这种工作方式在某些U N I X的页式虚存实现中提高了效率(与上节中提及的,在f o r k之后跟随
e x e c,并采用在写时复制技术相类似)。
v f o r k和f o r k之间的另一个区别是: v f o r k保证子进程先运行,在它调用e x e c或e x i t之后父进
程才可能被调度运行。(如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会
导致死锁。)
v f o r k起源于较早的4 B S D虚存版本。在L e ffler 等〔1 9 8 9〕的5 . 7节中指出:“虽
然它是特别有效率的,但是v f o r k的语义很奇特,通常认为它具有结构上的缺陷。”
尽管如此S V R 4和4 . 3 + B S D仍支持v f o r k。
某些系统具有头文件,当调用v f o r k时,应当包括该头文件。
v f o r k用于创建一个新进程,而该新进程的目的是e x e c一个新程序(如上节(2) 中一样)。程
序1 - 5中的s h e l l基本部分就是这种类型程序的一个例子。v f o r k与f o r k一样都创建一个子进程,
但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用e x e c (或e x i t ),于
是也就不会存访该地址空间。不过在子进程调用e x e c或e x i t之前,它在父进程的空间中运行。
这种工作方式在某些U N I X的页式虚存实现中提高了效率(与上节中提及的,在f o r k之后跟随
e x e c,并采用在写时复制技术相类似)。
v f o r k和f o r k之间的另一个区别是: v f o r k保证子进程先运行,在它调用e x e c或e x i t之后父进
程才可能被调度运行。(如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会
导致死锁。)
|
e x i t和_ e x i t函数用于正常终止一个程序: _ e x i t立即进入内核, e x i t则先执行一些清除处理
(包括调用执行各终止处理程序,关闭所有标准I / O流等),然后进入内核。
(包括调用执行各终止处理程序,关闭所有标准I / O流等),然后进入内核。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。