当前位置: 技术问答>linux和unix
一个关于fork进程的问题
来源: 互联网 发布时间:2015-10-14
本文导语: 很简单的一段代码: #include int main(int argc , char **argv) { int i; int pid; for ( i = 0 ; i fork_test # Parent:9228 # Child:9229 ## fork print is : 0 # Parent:9228 # Child:9230 ## fork print is : 1 # Parent:922...
很简单的一段代码:
#include
int main(int argc , char **argv)
{
int i;
int pid;
for ( i = 0 ; i fork_test
# Parent:9228 # Child:9229 ## fork print is : 0
# Parent:9228 # Child:9230 ## fork print is : 1
# Parent:9228 # Child:9231 ## fork print is : 2
[sybase]/export/home/sybase/lrj/bin> # Parent:9229 # Child:9232 ## fork print is
: 1
# Parent:9230 # Child:9233 ## fork print is : 2
# Parent:9229 # Child:9234 ## fork print is : 2
# Parent:9232 # Child:9235 ## fork print is : 2
(不出现命令行提示符,光标停在此处)
并且每次运行该程序结果不一样。
本人很想知道的是:这个程序(主要是fork()调用)的运行机制到底是怎样的,才会出现上述的结果?
#include
int main(int argc , char **argv)
{
int i;
int pid;
for ( i = 0 ; i fork_test
# Parent:9228 # Child:9229 ## fork print is : 0
# Parent:9228 # Child:9230 ## fork print is : 1
# Parent:9228 # Child:9231 ## fork print is : 2
[sybase]/export/home/sybase/lrj/bin> # Parent:9229 # Child:9232 ## fork print is
: 1
# Parent:9230 # Child:9233 ## fork print is : 2
# Parent:9229 # Child:9234 ## fork print is : 2
# Parent:9232 # Child:9235 ## fork print is : 2
(不出现命令行提示符,光标停在此处)
并且每次运行该程序结果不一样。
本人很想知道的是:这个程序(主要是fork()调用)的运行机制到底是怎样的,才会出现上述的结果?
|
这个问题我分析了一下,确实挺有意思的。
子进程会完全克隆主进程,这每个人都很清楚。
这样每个子进程都会继续循环下去继续产生新的子进程,这也是对的,但为什么会产生楼主所示的情况呢,我认为可能是一下原因:
首先第一个进程(父进程,楼主的是9228进程),在第一次循环它会产生一个子进程(9229)这时就出现了第一条打印信息。接着9229将继承9228的一切,包括资源(例如变量i的值),这时i=1,这是9228和9229会同时做一件事(继续循环创建子进程,i是从1开始的),他们分别创建了9230、9232这两个子进程,于是就出现了第二条和第四条打印信息(# Parent:9228 # Child:9230 ## fork print is : 1 # Parent:9229 # Child:9232 ## fork print is
: 1)。接着会有4个进程做同样的事情,(这时i已经等于2了,是最后一次循环了),他们又分别创建了四个子进程(9231,9233,9324,9235)。接着整个程序就运行完了。至于命令行跑到中间,光标停在最后不动了,那都是标准输出缓冲的问题,跟这个程序没有一点关系。虽然每次结果不同,但是你们可以发现一些规律,就是9228创建了三个进程(因为循环了三次),9229创建了两个进程(循环了两次),9230和9232分别创建了一个进程。因为是并行的,所以顺序有时候会不一样。
子进程会完全克隆主进程,这每个人都很清楚。
这样每个子进程都会继续循环下去继续产生新的子进程,这也是对的,但为什么会产生楼主所示的情况呢,我认为可能是一下原因:
首先第一个进程(父进程,楼主的是9228进程),在第一次循环它会产生一个子进程(9229)这时就出现了第一条打印信息。接着9229将继承9228的一切,包括资源(例如变量i的值),这时i=1,这是9228和9229会同时做一件事(继续循环创建子进程,i是从1开始的),他们分别创建了9230、9232这两个子进程,于是就出现了第二条和第四条打印信息(# Parent:9228 # Child:9230 ## fork print is : 1 # Parent:9229 # Child:9232 ## fork print is
: 1)。接着会有4个进程做同样的事情,(这时i已经等于2了,是最后一次循环了),他们又分别创建了四个子进程(9231,9233,9324,9235)。接着整个程序就运行完了。至于命令行跑到中间,光标停在最后不动了,那都是标准输出缓冲的问题,跟这个程序没有一点关系。虽然每次结果不同,但是你们可以发现一些规律,就是9228创建了三个进程(因为循环了三次),9229创建了两个进程(循环了两次),9230和9232分别创建了一个进程。因为是并行的,所以顺序有时候会不一样。
|
子进程被创建之后把所有父进程的数据都作一份拷贝,并且继续向下执行,注意下面的打印,
父进程创建了子进程9232之后,9232又变成父进程产生子进程9235,直到i的值增加到3,fork才结束。
如果系统没有机会执行父进程的++i的操作,这个fork递归执行下去。
所以在创建子进程之后父进程一般会退出或者等待。
[sybase]/export/home/sybase/lrj/bin> # Parent:9229 # Child:9232 ## fork print is
: 1
# Parent:9230 # Child:9233 ## fork print is : 2
# Parent:9229 # Child:9234 ## fork print is : 2
# Parent:9232 # Child:9235 ## fork print is : 2
父进程创建了子进程9232之后,9232又变成父进程产生子进程9235,直到i的值增加到3,fork才结束。
如果系统没有机会执行父进程的++i的操作,这个fork递归执行下去。
所以在创建子进程之后父进程一般会退出或者等待。
[sybase]/export/home/sybase/lrj/bin> # Parent:9229 # Child:9232 ## fork print is
: 1
# Parent:9230 # Child:9233 ## fork print is : 2
# Parent:9229 # Child:9234 ## fork print is : 2
# Parent:9232 # Child:9235 ## fork print is : 2
|
fork后,会有两个进程运行。父进程和子进程都运行!
更仔细全面的请看《高级环境编程》
更仔细全面的请看《高级环境编程》
|
光标肯可能是因为主进程比子进程先退出.
在子进程里 printf("# Parent : %d # Child : %d ## fork print is : %dn" , getppid() ,
getpid() , i); 这个i的值是创建子进程时对父进程的拷贝.
子进程里的i和主进程里的i是两回事. 也就是说父进程中的i改变了,不会改变子进程中的i.
在子进程里 printf("# Parent : %d # Child : %d ## fork print is : %dn" , getppid() ,
getpid() , i); 这个i的值是创建子进程时对父进程的拷贝.
子进程里的i和主进程里的i是两回事. 也就是说父进程中的i改变了,不会改变子进程中的i.