• fork 创建进程的过程分析


    本文为我学习linux内核的总结。

    唐建 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000。

    1、概述

      前面分析了系统调用的原理和过程。本文分析fork这个系统调用,重点分析进程的创建主要动作和流程。

    2、fork 系统调用的主要动作

      

      如上图,fork、vfork、clone,最终都是调用do_fork。不过他们之间的差异也可以在do_fork及后续代码中看到,不过这里不讲述。

          do_fork 的主要逻辑为调用copy_process,又函数名就可以看到进程的生成逻辑就在copy_process.

      copy_process主要调用了:

            dup_task_struct()——主要是创建和复制进程

             copy_fs            ——拷贝文件句柄之类的

      copy_files         ——拷贝文件句柄之类的

            copy_mm         ——拷贝虚拟内存

      copy_io             ——拷贝io

      copy_thread     ——拷贝thead_info信息

           下面我们着重分析 dup_task_struct 和 copy_thread 。    

         2.1 、dup_task_struct:申请内存,拷贝task_struct和thread_info       

      如上图所示,前面两个调用为申请task_struct、thread_info 的内存,arch_dup_task_struct就是将父进程的

      task_struct 拷贝给子进程。

           setup_thread_stack:这个函数是将父进程的堆栈thread_info拷贝给子进程。

      

       2.2、copy_thread :准备栈信息

     如上图信息childregs保存父进程的堆栈信息,然后赋值给子进程堆栈。右图pt_regs为系统调用开始通过save_all保存的信息。

    同时可以看到如果是内核创建线程走的不同的分支,不同的处理。

    上面可以看到childregs->ax=0,就是返回值,也就是子进程返回的pid为0的原因。

    p->thread.ip = (unsigned long) ret_from_fork,前面设置了sp栈顶,这里再设置ip。

    ret_from_fork->syscall_exit。这里就很熟悉了,就是我们上一篇博客中的系统调用完成后的执行过程,ip为子进程执行的起点,所以可以知道
    子进程开始调度时是从ret_from_fork开始执行的。
    2.3、父进程

    如上图所示,子进程完全准备完毕,获取子进程id作用父进程的返回值,同时唤醒子进程。这样两个进程都可以运行了 。

    3、debug

      下面我们来跟踪fork内核执行过程,我们断住主要函数do_fork、copy_process、dup_task_struct、copy_thread 、

    ret_from_fork

    4、总结

      fork创建一个进程,实际上就将父进程的进程信息拷贝给子进程,子进程的起点就是父进程系统调用结束的位置。只有子进程信息完全准备好后,父进程要返回前才唤醒子进程。

    
    

      





  • 相关阅读:
    css 设置特定条件下的标签
    vue实现导航菜单滚动
    input 默认样式样式 样式修改
    vue 倒计时
    微信小程序 botton默认样式删除
    Notepad++ 快捷键
    css实现div水平垂直居中
    Python爬虫爬取1905电影网视频电影并存储到mysql数据库
    Python爬虫爬取搜狐视频电影并存储到mysql数据库
    第一阶段(十)
  • 原文地址:https://www.cnblogs.com/tjyuanxi/p/9245563.html
Copyright © 2020-2023  润新知