fork()函数函数总结

学习操作系统进程时遇到用fork创建子进程,一下所写均是个人结合网上一些资料和个人思考所得,欢迎拍砖!

【进程创建的原因】

导致进程创建的一般有事件有:1新的批处理作业、2交互登陆(终端用户登陆到系统)、3操作系统因为提供一项服务而创建、4由现有的进程派生。

*注:操作系统为另一个进程的显示请求创建一个进程时,这个动作称为进程派生。

父进程与子进程:当一个进程派生另外一个进程时,前一个称做父进程,被派生的进程称做子进程。

【引入fork()函数】

UNIX中的进程创建是通过内核系统调用fork()实现的。POSIX 标准中,fork 的行为是这样的:复制整个用户空间的数据以及所有系统对象,然后仅复制当前线程到子进程。

当一个进程产生一个fork请求时,操作系统执行以下功能:

1)为新进程(子进程)在进程表中分配一个空项和赋予一个唯一的进程ID(标识符)。

2)子进程继承了父进程所有的文件。

fork()成功完成后,子进程返回0,父进程返回子进程ID,父子进程继续执行fork()函数。否则,父进程返回-1,子进程不能创建并应设置error以指示错误。

   1: #include <sys/types.h>
   2: #include <unistd.h>
   3: #include <iostream>
   4:  
   5: using namespace std;
   6: main()
   7: {
   8:     pid_t fpid;
   9:     fpid = fork();   //fpid得到的就是子进程本身的pid
  10:     if (fpid<0)
  11:         cout << "error in fork!"<<endl;
  12:     else if (fpid==0)
  13:         cout<<"This is chile"<<endl;
  14:     else
  15:         cout<<"This is parent!"<<endl;
  16: }
运行结果:
image
对于新手来说,无论如何思考,得到的执行效果只能是"This is parent!"或者“This is chile"其中一个。下面我引用一个网友所写和个人修改:

当程序执行到语句:pid=fork(); 
操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互 独立的进程!此时程序寄存器pc,在父、子进程的上下文中都声称,这个进程目前执行到fork调用即将返回(此时子进程不占有CPU,子进程的pc不是真正保存在寄存器中,而是作为进程上下文保存在进程表中 的对应表项内)。问题是怎么返回,在父子进程中就分道扬镳。
父进程继续执行,操作系统对fork的实现,使这个调用在父进程中返回刚刚创建的子进程的pid(一个正整数),所以下面的if语句中pid<0, pid==0的两个分支都不会执行。所以输出                               

This is parent...
子进程在之后的某个时候得到调度,它的上下文被换入,占据 CPU,操作系统对fork的实现,使得子进程中fork调用返回0。所以在这个进程(注意这不是父进程了哦,虽然是同一个程序,但是这是同一个程序的另外一次执行,在操作系统中这次执行是由另外一个进程表示的,从执行的角度说和父进程相互独立)中pid=0。这个进程继续执行的过程中,if语句中pid<0不满足,但是pid==0是true。所以输出          

This is child...
我想你比较困惑的就是,为什么看上去程序中互斥的两个分支都被执行了。在一个程序的一次执行中,这当然是不可能的;但是你看到的两行输出是来自两个进程,这两个进程来自同一个程序的两次执行。    

posted @ 2013-04-29 18:23  hww836967373  阅读(200)  评论(0编辑  收藏  举报