基础文章3:进程基础之fork函数

来源:互联网 发布:软件开发说明书 编辑:程序博客网 时间:2024/05/16 01:24
0.序
1.基础内容介绍
     1)进程的组成:  
     2)fork函数调用后,系统所做工作:
2.函数详细介绍
     1)函数原型
     2)作用
     3)描述
3.总结:
0.序
     fork函数是Linux中创建进程的函数,也是唯一一个创建进程的函数。因此学好fork函数时基础中的基础。0.序
1.基础内容介绍
     1)进程的概述:
       进程简单的说就是一个程序一次执行的过程,它是一个动态的概念。按照教科书上的定义,进程是程序执行的实例,是linux的基本调度单位。 
     对于程序员来说,最重要的就是要区分进程和程序的区别,程序是指一段完成功能的代码,或者说是一个工具,它是一个静态的概念,而进程,它是动态的,比如,linux的vi编辑器,它就是一段在linux下用于文本编辑的工具,那么它是一个程序,而我们在linux终端中,可以分别开启两个vi编辑器的进程。一旦提到进程,我们的脑子里就应该产生——程序从代码的第一句动态的执行到最后一句这样的一个思路。 
一个进程由如下元素组成: 
1.> 进程的当前上下文,即进程的当前执行状态; 
2.> 进程的当前执行目录 
3.> 进程访问的文件和目录 
4.> 进程的访问权限,比如它的文件模式和所有权 
          5.> 内存和其他分配给进程的系统资源 
  
        fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
      2)fork函数调用后,系统所做工作:
               一个进程调用fork()函数后,
                    (1)系统先给新的进程分配资源,例如存储数据和代码的空间。
                    (2)然后把原来的进程的所有值都复制到新的新进程中,只有少数值(这部分少数值在man fork中有详细说明)与原来的进程的值不同。相当于克隆了一个自己。
2.函数详细介绍
     1)函数原型
SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);
     2)作用
          创建一个子进程。是进程不是线程。
     3)描述
         ( 1)通过复制调用进程(即父进程)来创建一个子进程。
               所谓复制:子进程会与父进程共享代码空间,但是其数据空间是相互独立的。子进程的数据空间是从父进程完成拷贝下来的,刚创建完子进程时里面的取值都与父进程一样,但是由于其数据空间是相互独立的,因此数据空间中的数据会随着子进程的进行,而发生改变,从而与父进程不再一样。
               fork函数的作用是在其进程中创建一个新的进程,这个新的进程不会取代原来的进程,而是以当前进程的一个子进程而存在的。这个子进程会有一个新的进程标识符pid。并且这个子进程会继承父进程的一切! 
          什么是叫继承父进程的一切呢?就是克隆父进程的所有,包括父进程的代码父进程正在执行的状态父进程的工作目录父进程的所有资源等等,一切的一切,fork系统调用会全部的复制下来。
        
               举例:
/*可以用于说明父子进程间数据空间是相互独立的*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


int glob = 6;
char buf[] = "a write to stdout/n";


int main()
{
    int var;
    pid_t pid;

    var = 88;


    fprintf(stderr, "%s", buf);

    printf("before fork\n");

    if(( pid = fork() ) < 0 )
    {
        fprintf(stderr, "fork error\n");
    }
    else if(pid == 0)
    {

        glob++;
        var++;
        printf("child process\n");
printf("pid = %d getpid = %d, father pid = %d, glob = %d, var = %d\n",pid, getpid(), getppid(), glob, var);
        exit(0);
    }
    else
    {
        var += 20;
        glob += 20;
        printf("begin into father process\n");
        sleep(2);
        printf("father process\n");
        printf("pid = %d, father pid = %d, glob = %d, var = %d\n", getpid(), getppid(), glob, var);
    }


    return 0;
}
运行结果
a write to stdout/nbefore fork
begin into father process
child process
pid = 0 getpid = 4039, father pid = 4038, glob = 7, var = 89
father process
pid = 4038, father pid = 3317, glob = 26, var = 108

           (2)创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略
           (3)当创建完毕后,可以想象,两个进程一直同时进行,而且步调一致,在fork之后,他们分别做不同的工作,也就是分岔了,这就是为什么叫fork的原因. fork执行完毕后,出现两个进程。
                    根据1)中所述,父子进程共享代码空间,因此二者代码相同。又根据1)中所述,二者数据空间相互独立,根据fork在父进程与子进程的返回值的不同,父子进程将会执行不同的代码段,从而实现不同的功能。

          4)特别重要的一点:fork是把进程当前的情况拷贝一份。切记是当前的情况拷贝一份,而不是代码中原始数据的拷贝。这一点通过下面的代码最能体现。
#include <unistd.h> 
#include <stdio.h> 
int main(void) 

   int i=0; 
   printf("i son/pa ppid pid  fpid\n"); 
   //ppid指当前进程的父进程pid 
   //pid指当前进程的pid, 
   //fpid指fork返回给当前进程的值 
   for(i=0;i<2;i++){ 
       pid_t fpid=fork(); 
       if(fpid==0) 
           printf("%d child  %4d %4d %4d\n",i,getppid(),getpid(),fpid); 
       else 
           printf("%d parent %4d %4d %4d\n",i,getppid(),getpid(),fpid); 
   } 
   return 0; 
}  

  其运行结果
 
i son/pa ppid pid  fpid
0 parent 3317 4096 4097
1 parent 3317 4096 4098
 1 child     1 4098    0
0 child     1 4097    0
1 parent    1 4097 4099
1 child     1 4099    0

        之所以运行结果的顺序与http://blog.csdn.net/jason314/article/details/5640969 文中不同,我想就是因为这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。    
3.总结:
          fork()函数通过系统调用创建了一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事(因为共享代码空间),但是由于fork函数的返回值的不同,会产生不同的功能(fork返回值不同,会去执行不同代码段,又因为数据空间是相互独立,故数据互不影响)。
          重点记住两点:1)共享程序空间,数据空间相互独立
                                   2)父子进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

相关文章 http://blog.csdn.net/jason314/article/details/5640969 
               http://blog.csdn.net/dog_in_yellow/article/details/2041079 
http://xuzhigang921.blog.163.com/blog/static/56199220201123122639986/ 
http://coolshell.cn/articles/7965.html 一个fork的面试题
原创粉丝点击