linux: fork系统调用实现剖析

首先了解一下程序和进程的概念:

      程序:程序是完成特定任务的一系列指令集合。

      进程:从用户角度来看,进程是程序的一次执行过程。从系统的角度看,进程是操作系统分配内存和cpu等资源的基本单位,进程是资源分配的最小单位。每一个进程都有自己独立的地址空间与执行状态,像unix这样的多任务操作系统能够让许多程序同时运行,每一个运行着的程序就构成了一个进程。
     进程数据结构:
          进程的静态描述:由pcb、有关程序段和该程序段所操作的数据结构集。
          进程控制块:描述进程情况及控制运行所需要的全部信息
          代码段:是进程中能够被进程调度程序在cpu上执行的代码段
           数据段:一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行完毕后产生的中间或者最终数据
     进程和程序的区别:
          进程是动态的,程序是静态的。
          进程的生命周期是相对短暂的,而程序是永久的。
          进程数据结构PCB。
          一个进程只能对应一个程序,一个程序可以对应多个进程。
      进程的状态:就绪、运行、等待(阻塞)
技术分享      linux内核的进程状态:运行、可中断睡眠、不可中断睡眠、暂停、僵尸等状态,他们的图如下图:
技术分享
技术分享
     进程调度及其算法:先来先服务算法、时间片轮转法等
     0号进程是linux的生命,是内核启动的时候的天字第一号进程。创建完第一个0号进程后,会第一个用户进程就是1号进程, which init/sbin
查看内核进程pid最大配置:cat /proc/sys/kernel/pid_max 32768个
     下面来进入主题:
fork系统调用
    fork函数的现象就是开启一个新的进程分支,会出现并发情况。
    fork函数调用时怎样做到一次调用两次返回的呢?本质上是进程都在各自的内存空间返回,因为每个进程都有自己的内存空间。
    子进程拷贝父进程的哪些数据资源呢?代码段、堆栈、数据段、进程控制块(记录了进程的状态,cpu通过进程控制块查询进程的状态)
    一个进程是由进程PCB、代码段、数据段、堆栈段。进程是操作系统对资源的一种抽象,PCB是操作系统感知进程存在的一个重要数据结构,言外之意就是会所cpu通过PCB来控制进程。
   如果此时在数据段和代码段中有一个文件锁,子进程会拷贝吗?
   如果父进程中打开一个文件,那么文件句柄会被子进程拷贝吗?
    如果父进程中有一个变量,那么子进程中的变量和父进程中的变量是同一个变量吗?不是,每个进程都有独立的内存空间。
   fork函数的返回值是等于0是子进程,大于0是父进程,为什么这样做呢?返回值是子进程的id号,这样父进程可以很方便的控制子进程。一个父进程可以不断的fork子进程,父进程和子进程是一对多的关系,如果创建一个子进程不把子进程的信息返回给父进程,那么父进程就无法控制多个子进程。再者在子进程中获取父进程也是很方便。如果fork进程出错了怎么办?man 2 fork,失败的话返回-1,会创建一个变量errno记录错误信息。
    怎么理解子进程的应用代码从fork开始,而不是从声明pid_t变量开始呢?
    pid_t pid;    
    int abc= 6;// 父进程到此处还是改数据段赋值
    pid = fork();// 拷贝数据给子进程,没有必要让子进程再赋值
    if(pid==-1){
        //子进程从此处开始执行
    }
技术分享
下列和helloword会打印几次?8次
int main(){
    fork(); // 会产生两个进程分支
    fork();// 前面产生的两个进程每个都会产生两个进程,有四个进程
    fork();// 前面产生的4个进程都会产生两个进程,总共有八个进程
    print("helloworld!");// 八个进程所以会打印八次
    return 0;
}

让父进程产生10个进程,请输入要产生多少个进程,每个进程要跑多少圈?
void testFunction(){
    print("------------------");
}
int main(){
        int procnum = 10;
        int loopnum = 100;
        int i = 0;
        pid_t pid;
        for( i=0;i<10;i++){
            pid = fork();
            if (pid){
                for(j =0;j<loopnum ;j++){
                         testFunciton();
                }  
                exit(0);
            }
        }

}

本文来源:http://blog.csdn.net/andywuchuanlong

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。