深刻理解fork调用

  fork()是linux中的系统调用函数,用于创建进程,创建失败返回-1,创建成功会返回两次(不是返回了两个值,而是返回了两次)。需要注意的是fork调用一次返回两次:对父进程而言它返回的是子进程的id,对子进程而言它返回0。

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


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>  // 系统调用的封装
#include<sys/wait.h>  //wait/waitpid时使用

int main()
{
	printf("父进程! pid=%d\n",getpid());
	pid_t p1id=fork();  //如果fork成功,会向父进程返回子进程的id,并向子进程0
	printf("第一次%d\n",(int)p1id);
	if(p1id<0)
	{
		printf("fork创建子进程1失败!\n");
		exit(1);
	}
	else if(p1id==0)
	{
		for(int i=0;i<9;i++)
			printf("这是子进程1,id为:%d,它的父进程id为:%d\n",(int)getpid(),(int)getppid());
		return 0;
	}
	
	//创建第二个进程
	pid_t p2id=fork();
	printf("第二次%d\n",(int)p2id);
	if(p2id<0)
	{
		printf("fork创建子进程2失败!\n");
		exit(2);
	}
	else if(p2id==0)
	{
		for(int i=0;i<5;i++)
		{
			printf("这是子进程2,id为:%d,它的父进程id为:%d\n",(int)getpid(),(int)getppid());
		}
		return 0;
	}
	
	waitpid(p1id,NULL,0);
	waitpid(p2id,NULL,0);
	printf("这是父进程,父进程id为:%d\n",getpid());
	return 0;
	
	

运行上述代码结果如下:


       可见,第一次创建返回两次,一次是6433,恰好对应其子进程的id;一次是0,即在子进程中的反回0,if(p1id==0)部分对应子进程1的内容。

          第二次创建同样返回两次,一次是6434,恰好对应其子进程的id;一次是0,即在子进程2中返回0,if(pid2==0)部分对应子进程2的内容。  (上面除if(pid==1)和if)(pid==2)的内容外,其他都是父进程的内容)

          重复运行以上程序,那四个返回值出现的位置不同,说明父进程与两个子进程各自执行。但为什么在上述情况下两子进程内部的输出始终是各自连续的??(删除显示p1id p2id的语句,两部分输出就会是交错的!!!)可能这和内部时间分配策略有关,其实只要增加循环次数,会发现即使不删除那两个语句,输出也会是交错的。


注意,当将子进程内部的return 改为exit时,能够按照预期运行;如果删除return,则部分内容执行次数多余预期。如下,最后一句执行了四次,子进程2也重复执行了。


原因如下:子进程的结束应该使用exit(),但是在main函数中,使用exit和使用return的表观效果一样(实质不同);

                    至于为什么没有使用exit导致重复执行,至今尚步明白!!???


    

 

猜你喜欢

转载自blog.csdn.net/qq_37979572/article/details/80443459