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导致重复执行,至今尚步明白!!???