fork()-实例分析

1、子进程对存储空间的复制

(1) 使用文本编辑器输入源程序

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
 
int main(void)
{
    int x, i;
 
    printf("Input a initial value for i: ");
    scanf("%d", &i);
    while((x=fork())==-1);//创建一个子进程,止到创建成功
    if(x==0)         
    {
        printf("When child runs, i=%d\n", i);
        printf("Input a value in child: ");
        scanf("%d", &i);
        printf("i=%d\n", i);
    }
    else         
    {
        wait();
        printf("After child runs, in parent, i=%d\n", i);
    }
}

(2) 实际执行结果分析

Input a initial value for i: 4
When child runs, i=4
Input a value in child: 2
i=2
After child runs, in parent, i=4

结果分析:

父进程执行,输出Input a initial value for i:后IO中断,释放CPU,父进程进入阻塞状态,输入4完成后,父进程由阻塞状态,得到CPU后再次进入执行状态。执行while((x=fork())==-1);后,父进程创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的fork()返回值为0,父进程的fork()返回值为刚创建的子进程号。系统先运行父进程因pid=fork()=子进程号,进入else分支,遇到wait()父进程释放CPU让子进程先执行完后再执行,子进程的pid=fork()=0,进入if(pid==0)下的分支,进入该分支后,因出现IO中断,处理IO后子进程结束,再执行父进程。


2、父子进程执行过程分析

 (1) 按照给定框架编程

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
	// ①
	pid_t pid=fork(); 
	// ②  
	if(pid==0)
	{
                sleep(3);           
              	printf("Child: pid=%d, ppid=%d\n", getpid(), getppid());         
	}
	else          
	{  
         	printf("Parent: Child=%d, pid=%d, ppid=%d\n", pid, getpid(), getppid());
              	wait(); 
            	printf("After Child ends.\n");       
	}
	printf("In which process?\n");      // ③
	return 1;
}

(2) 实际执行结果分析

编译生成执行文件,执行后记录结果,说明与预期的结果是否一致。分析为什么是这样的结果。

执行结果:

ParentLChild=12842,pid=12841,ppid=12811

Child:pid=12842,ppid=12841

In which process?

After Child ends.

In which process?

分析:

父进程执行,遇到fork()时,父进程创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的fork()返回值为0,父进程的fork()返回值为刚创建的子进程号。系统先运行父进程,子进程的pid=fork()=子进程号,进入else分支,输出子进程号12842、自身进程号12841,自身分进程号12811.之后执行wait(),父进程释放CPU让子进程先执行完。进入子进程,pid=fork()=0,进入if(pid==0)分支,sleep(3);使子进程进入睡眠状态3秒,输出屏幕上会等待一会儿,即等待子进程醒来,之后输出子进程号12842、父进程号12841,最后子进程输出“In which process?”。子进程执行完成释放CPU,父进程获得CPU继续执行,输出“After Child ends.”,然后输出“In which process?”,父进程结束。


(3) 修改程序并分析执行结果

把程序框架中最后一句输出语句(位置③处)分别移至位置①和②处,预期输出结果是什么?实际执行结果如何?分析原因。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
	printf("A In which process?\n");
	pid_t pid=fork(); 
	printf("B In which process?\n"); 
	if(pid==0)
	{
                sleep(3);           
              	printf("Child: pid=%d, ppid=%d\n", getpid(), getppid());         
	}
	else          
	{  
         	printf("Parent: Child=%d, pid=%d, ppid=%d\n", pid, getpid(), getppid());
              	wait(); 
            	printf("After Child ends.\n");       
	}
	return 1;
}

运行结果:

A In which process?

B In which process?

Parent:Child=12915,pid=12914,ppid=12811

B In which process?

Child:pid=12915,ppid=12914

After Child ends.

分析:

当前进程执行,输出“A In which process?”,然后遇到fork(),父进程,即当前进程,创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的fork()返回值为0,父进程的fork()返回值为刚创建的子进程号。系统先运行父进程,输出“B In which process?”,pid=fork()=子进程号,父进程进入else下的分支,输出子进程号12815、自身进程号12814,自身分进程号12811.之后执行wait(),父进程释放CPU让子进程先执行完。之后执行子进程,输出“B In which process?”,子进程的pid=fork()=0,进入if(pid==0)下的分支,进入该分支后,sleep(3);使子进程进入睡眠状态(3秒),释放CPU,但此时父进程还在wait()子进程结束,子进程此时还在睡眠状态,输出屏幕上会等待一会儿,即等待子进程醒来,之后输出子进程号12815、父进程号12841。子进程执行完成释放CPU,父进程获得CPU继续执行,输出“After Child ends.”,父进程结束。


(4) 修改程序验证父子进程关系

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
	printf("A In which process?\n");
	pid_t pid=fork(); 
	printf("B In which process?\n"); 
	if(pid==0)
	{
                sleep(3);           
              	printf("Child: pid=%d, ppid=%d\n", getpid(), getppid());         
	}
	else          
	{  
         	printf("Parent: Child=%d, pid=%d, ppid=%d\n", pid, getpid(), getppid());
                printf("After Child ends.\n");       
	}
	return 1;
}
程序修改:将else里的wait();语句去掉。

执行结果:

A In which process?
B In which process?
Parent: Child=14372, pid=14371, ppid=12483
After Child ends.
nanfeng@ubuntu:~/python-test$ B In which process?
Child: pid=14372, ppid=1

分析:

当前进程执行,输出“A In which process?”,然后遇到fork(),父进程,即当前进程,创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的fork()返回值为0,父进程的fork()返回值为刚创建的子进程号。系统先运行父进程,输出“B In which process?”,pid=fork()=子进程号,父进程进入else下的分支,输出子进程号12824、自身进程号12823,自身分进程号12811.,然后输出“After Child ends.”,父进程执行完,释放CPU,并把子进程抛给了最底层系统进程,进程号为1。进程号为1的父进程得到CPU后执行,输出“[root@localhost root]#”,提示用户输入命令,此时发生IO中断,进程号为1的父进程释放CPU。进入子进程,输出“B In which process?”,之后子进程的pid=fork()=0,进入if(pid==0)下的分支,进入该分支后,sleep(3);使子进程进入睡眠状态,释放CPU,3秒完后继续执行子进程,此时子进程醒来,之后输出子进程号12924、父进程号1。子进程执行完成释放CPU,进程号为1的父进程继续执行。



总结:遇到fork(),父进程,即当前进程,创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的fork()返回值为0,父进程的fork()返回值为刚创建的子进程号。系统先运行父进程。某个进程遇到wait()时,等待其它进程执行完再执行该进程。


来源:http://blog.sina.com.cn/s/blog_6334fe7c0100fvtf.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值