进程创建函数fork()

函数原型: pid_t fork(void)

头文件:  #include <unistd.h>

函数功能: 创建一个子进程

返回值:  1.   -1 创建失败

       2.   0 返回的是子进程

       3.   >0 返回的是父进程,返回值是子进程ID

函数特性:  1. 调用一次,会有两个返回值

      2. 先返回哪个值,不确定,一般先返回父进程

      3. 用户可以通过延时函数,决定进程的执行先后顺序。

      4. 创建后,子进程复制父进程空间,这个空间子进程所独有的只有它的进程号、计数器和资源使用,其他的和父进程

        空间一样,两个空间相互独立,互不干涉即使全局变量,在子进程中不会随父进程中变量的值的改变而改变。

函数框架:       

1 #inlcude <stdio.h>
 2 #include <unisd.h>
 3 int main()
 4 {
 5     pid_t    pid;
 6     //父进程独有
 7     pid = fork();
 8     //父子进程共有
 9     if(pid < 0)
10     {    
11         printf(“establish error!\n”);
12         return -1;
13     }
14     else if(pid == 0)
15     {    
16         //子进程独有
17         //子进程
18     }
19     else if(pid > 0)
20     {    
21         //父进程独有
22         //父进程
23     }
24     //父子进程共有
25 }    

      分析:独有的只会运行一次,共有的会运行两次。

 

进程切换: 1. 通过延时类函数(可控):  sleeps延时) usleepus延时)

      2. 时间片到了(不可控)

      注意: 延时会让程序处于等待态,所谓等待态,就是先去运行已经处于就绪态的程序,什么时候延时时间到了,程序

          就会处于就绪态。等其他程序运行完,或者时间片到了,再切换回来,从上次的断点处继续运行。两个进程之间

          没有优先级关系,不存在打断关系,只有子进程运行完了,或者进入等待态,或者时间片到了才会进入父进程。

      示例: 下面的代码示例,如果没有时间片的影响,在进入子进程以后,会一直卡在子进程,永远不会再回到父进程,因

          受时间片的影响,还会过一段时间就切换回父进程。 

  #include <stdio.h>                                                                              
  2 #include <unistd.h>
  3 int main()
  4 {
  5     int num_father = 1;
  6     int num_son = 1;
  7     pid_t pid;
  8     pid = fork();
  9     if(pid < 0)
 10     {
 11         printf("error\n");
 12         return -1;
 13     }
 14     else if(pid == 0)
 15     {
 16         num_son++;
 17         printf("son\n");
 18         while(1)
 19         {
 20             printf("num_son=%d\n",num_son);
 21         }
 22     }
 23     else if(pid >0)
 24     {
 25         num_father++;
 26         printf("father\n");
 27         while(1)
 28         {
 29             usleep(1);
 30             printf("num_father = %d\n",num_father);
 31         }
 32     }
 33 }
代码最终运行结果是:一直打印num_son,偶尔会打印num_father。原因是卡在子进程了,因为时间片到了才会切回父进程,但是很快又回到了子进程。

 

执行流程:1. 父进程运行后,遇到fork()之前,都是父进程独有的程序

     2. 当遇到fork函数后,开始创建子进程,一般先返回父进程

      3. 在进入if框架之前,fork下的程序是子进程和父进程共有的

     4. 进入pid>0父进程独有的框架,如果父进程独有中无等待类操作,父进程独有的运行完,接着运行if框架外程序,

      直到父进程运行完,然后再运行子进程,这时候子进程已经变为了孤儿进程。

 1 #inlcude <stdio.h>
 2 #include <unisd.h>
 3 int main()
 4 {
 5     pid_t    pid;
 6     //父进程独有
 7     pid = fork();
 8     //父子进程共有
 9     if(pid < 0)
10     {    
11         printf(“establish error!\n”);
12         return -1;
13     }
14     else if(pid == 0)
15     {    
16         //子进程独有
17         //子进程
18     }
19     else if(pid > 0)
20     {    
21         //父进程独有
22         //父进程
23     }
24     //父子进程共有
25 }    

 

运行步骤:

         

    运行分析: fork有两个返回值,但是返回顺序有先后关系,第一个返回值是>0,先运行的是父进程,pid>0elseif运行结束后,

          父进程就结束了,此时,子进程变成了孤儿进程,被祖先进程接收,因为会返回两个返回值,所以又会返回一个

          值,程序从fork函数处又运行一遍,此时返回的是=0返回值的值,此时再运行==0elsif

示例代码:

        

     

 创建进程程序模板:

  条件: 1.避免孤儿进程和僵尸进程

       2.不存在父子进程共有的,全是独有的

  

   

 

posted on 2019-03-06 15:55  梦*飞  阅读(2516)  评论(0编辑  收藏  举报