当前位置: 技术问答>linux和unix
linux2.6 vfork是如何实现的
来源: 互联网 发布时间:2017-04-04
本文导语: 读apue第8章时,写了一个下面的程序 #include "apue.h" void f_vfork(); int main() { setbuf(stdout,NULL); f_vfork(); printf("process terminated. pid = %dn",getpid()); exit(0); } void f_vfork() { pid_t pid; if((pid=vfork())==-1) err_...
读apue第8章时,写了一个下面的程序
#include "apue.h"
void f_vfork();
int main()
{
setbuf(stdout,NULL);
f_vfork();
printf("process terminated. pid = %dn",getpid());
exit(0);
}
void f_vfork()
{
pid_t pid;
if((pid=vfork())==-1)
err_sys("vfork error");
else if(pid)
{
printf("parent output. pid=%dn",getpid());
}
else
{
printf("child output. pid=%dn",getpid());
}
}
它产生了如下的输出
child output. pid=3977
process terminated. pid = 3977
parent output. pid=3976
child output. pid=3978
预料中,当child返回时,它会破坏栈结构,使得父进程没能产生如下的输出
process terminated. pid = 3976
但是让人很不可思议的是 pid 为 3978的进程是从哪来的。
找了很多资料,也没能想明白,我想这只能从 vfork的实现入手来探寻原因了。
另外,如何查看gcc生成的汇编代码,我想从汇编代码入手或许也能解释这一奇怪的现象
#include "apue.h"
void f_vfork();
int main()
{
setbuf(stdout,NULL);
f_vfork();
printf("process terminated. pid = %dn",getpid());
exit(0);
}
void f_vfork()
{
pid_t pid;
if((pid=vfork())==-1)
err_sys("vfork error");
else if(pid)
{
printf("parent output. pid=%dn",getpid());
}
else
{
printf("child output. pid=%dn",getpid());
}
}
它产生了如下的输出
child output. pid=3977
process terminated. pid = 3977
parent output. pid=3976
child output. pid=3978
预料中,当child返回时,它会破坏栈结构,使得父进程没能产生如下的输出
process terminated. pid = 3976
但是让人很不可思议的是 pid 为 3978的进程是从哪来的。
找了很多资料,也没能想明白,我想这只能从 vfork的实现入手来探寻原因了。
另外,如何查看gcc生成的汇编代码,我想从汇编代码入手或许也能解释这一奇怪的现象
|
"如何查看gcc生成的汇编代码"
在Linux下使用objdump -d 命令反汇编。
在Linux下使用objdump -d 命令反汇编。
|
查看汇编也没用.
因为vfork时,汇编就是一个条系统调用的语句
因为vfork时,汇编就是一个条系统调用的语句
|
呵呵,也是哦!可以直接汇编不链接的,-S选项。
|
楼主不用研究这种了,,这个应该和具体实现有关,想研究可能得从内核实现,单纯从应用层汇编可能找不出来.
首先父进程能正常输出,这个肯定的.因为如下面说的,调用vfork的进程(父进程)会一直挂起,,直到从你的程序中子进程在main中exit...这并不会影响父进程的pc寄存器(指向正在执行的指令地址)..所以父进程在f_vfork中是能够正常运行的. 后面的可能是栈被破坏等等原因,就不正常了.
见man 2 vfork
Standard Description
(From POSIX.1) The vfork() function has the same effect as fork(2),
except that the behavior is undefined if the process created by vfork()
either modifies any data other than a variable of type pid_t used to
store the return value from vfork(), or returns from the function in
which vfork() was called, or calls any other function before success‐
fully calling _exit(2) or one of the exec(3) family of functions.
vfork() differs from fork(2) in that the calling thread is suspended
until the child terminates (either normally, by calling _exit(2), or
abnormally, after delivery of a fatal signal), or it makes a call to
execve(2). Until that point, the child shares all memory with its par‐
ent, including the stack. The child must not return from the current
function or call exit(3), but may call _exit(2).
研究这些东西其实并没有多大意义,,当然你想从汇编上来研究,当作学习也可以..那就得慢慢折腾了.
首先父进程能正常输出,这个肯定的.因为如下面说的,调用vfork的进程(父进程)会一直挂起,,直到从你的程序中子进程在main中exit...这并不会影响父进程的pc寄存器(指向正在执行的指令地址)..所以父进程在f_vfork中是能够正常运行的. 后面的可能是栈被破坏等等原因,就不正常了.
见man 2 vfork
Standard Description
(From POSIX.1) The vfork() function has the same effect as fork(2),
except that the behavior is undefined if the process created by vfork()
either modifies any data other than a variable of type pid_t used to
store the return value from vfork(), or returns from the function in
which vfork() was called, or calls any other function before success‐
fully calling _exit(2) or one of the exec(3) family of functions.
vfork() differs from fork(2) in that the calling thread is suspended
until the child terminates (either normally, by calling _exit(2), or
abnormally, after delivery of a fatal signal), or it makes a call to
execve(2). Until that point, the child shares all memory with its par‐
ent, including the stack. The child must not return from the current
function or call exit(3), but may call _exit(2).
研究这些东西其实并没有多大意义,,当然你想从汇编上来研究,当作学习也可以..那就得慢慢折腾了.