Linux分析第六周——进程的描述和进程的创建

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

一、知识要点:

task_struct

task_struct结构的分配使用的是alloc_task_struct宏,该宏就是简单地调用kmem_cache_alloc()task_struct_cachep缓存中分配。接着会使用alloc_thread_info宏分配thread_info结构。thread_info结构保存了特定于体系结构的汇编语言代码需要访问的那部分进程数据,包括执行域、可抢占标志和当前的CPU等信息。在分配thread_info结构的时,实际调用的是__get_free_pages(),64位下分配的是2个物理页(返回的是虚拟地址)。但是很显然thread_info结构是用不了2页的,剩余的内存其实是用作子进程的内核栈(不是stack_start参数指定的用户栈),可以通过end_of_stack()来计算栈顶位置。在分配完必要的结构后,会调用arch_dup_task_struct()拷贝父进程的task_struct结构到子进程的task_struct结构,如果父进程使用FPU或其他的CPU扩展寄存器,则要将这些寄存器的信息(在prepare_to_copy()中保存的)拷贝到子进程的task_struct结构中。
 

fork函数对应的内核处理过程sys_clone:

fork()系统调用对应的内核实现为sys_fork()sys_fork()是对do_fork()的简单封装,sys_fork()的任务是从处理器寄存器中提取由用户空间提供的信息,do_fork()负责进程的复制。fork()和clone()系统调用的入口点sys_vfork()sys_clone()也是调用的do_fork()

而其中关系着进程创建的主要是copy_processcopy_thread.copy_process()函数有7个参数,其中我们需要关心的有clone_flagsstack_startregscone_flags是一个标志集合,分为两部分:最低的字节指定了在子进程终止时发送给父进程的信号,其余的高位字节保存了各种真正的复制标志,如CLONE_FSCLONE_THREAD等。在用户层调用fork()时不能指定标志,所以默认的CLONE_FLAGS的值为SIGCHLD。
 

dup_task_struct: 

     

  • task_struct开辟内存tsk = alloc_task_struct_node(node);

  • thread_info开辟内存ti = alloc_thread_info_node(tsk, node);

  • 复制父进程的task_struct信息到新的task_structerr = arch_dup_task_struct(tsk, orig);
     

    int arch_dup_task_struct(struct task_struct dst, struct task_struct src)
    {
       dst = src;
       if (src->thread.xstate) {
          dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
                             GFP_KERNEL);
         if (!dst->thread.xstate)
             return -ENOMEM;
            memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
       }
        return 0;
    }

4)setup_thread_stack 设置线程栈

    
子进程的初始化:进程的用户栈的起始地址存储在task_struct结构的stack_start成员中,在初始化的时候使用的是父进程的用户栈地址,所以在子进程创建时会和父进程使用相同的用户栈,如果有任何一方修改栈的话,会重新拷贝一份,这是基于COW技术,以避免无用的复制。创建子进程为调度器类提供了调度进程的一个切入点,内核会调用sched_fork()函数,以便使调度器有机会对新进程进行设置。sched_fork()会初始化一些和调度相关的成员,并将进程设置为TASK_RUNNING状态。不过此时新的进程还没有放到CPU的执行队列中,所以新的进程不会被调度到。
 

新进程是从ret_from_fork处开始执行的。对于fork执行处理过程来说,父子进程共享同一段代码空间,”一次调用,两次返回“,其实对于调用fork的父进程来说,如果fork出来的子进程没有得到 调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进程的id。再看fork出来的子进程,由 copy_process函数可以看出,子进程的返回地址为ret_from_fork(和父进程在同一个代码点上返回),返回值直接置为0。所以当子进 程得到调度的时候,也从fork返回,返回值为0。ret_from_fork()调用schedule_tail()函数,用存放在栈中的值再装入所有寄存器,并强迫CPU返回到用户态。这样,eax寄存器就装过两个值,一个是子进程的值0,一个是父进程的值——子进程的PID。然后在fork()、vfork()或clone()返回时,新进程将开始执行。在不同的进程中返回不同的值。

执行过程图:

二、实验过程:

1.配置环境,登录实验楼网站。

按照上次实验的基本步骤,结合老师视频所讲,完成相关实验。

cd LinuxKernel

删除menu

然后从github上克隆相应的mengning/menu.git
 

2.测试menuOS,测试fork直接执行结果。

3.配置调试系统,进入gdb调试,利用file linux-3.18.6/vmlinux和target remote:1234来配置加载初始调试环境.

4.在linux内核进程创建可能用到的点设置断点分别为sys_clone,do_fork,dup_task_struct,copy_thread,copy_process和ret_from_fork.


三、总结:

Linux中,fork、vfork和clone三个系统调用都是通过调用do_fork来实现进程的创建,而fork()系统调用产生的子进程在系统调用处理过程中从ret_from_fork处开始执行。fork会产生父子进程,在父进程中,返回值是子进程的进程号;在子进程中,返回值为0。因此可通过返回值来判断当前进程是父进程还是子进程。使用fork函数得到的子进程是父进程的一个复制品,它从父进程处复制了整个进程的地址空间,包括进程上下文,进程堆栈,内存信息,打开的文件描述符,信号控制设定,进程优先级,进程组号,当前工作目录,根目录,资源限制,控制终端等。而子进程所独有的只是它的进程号,资源使用和计时器等。可以看出,使用fork函数的代价是很大的,它复制了父进程中的代码段,数据段和堆栈段里的大部分内容,使得fork函数的执行速度并不快。

Linux分析第六周——进程的描述和进程的创建的更多相关文章

  1. LINUX内核分析第六周学习总结——进程的描述与创建

    LINUX内核分析第六周学习总结--进程的描述与创建 标签(空格分隔): 20135321余佳源 余佳源 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc ...

  2. LINUX内核分析第六周学习总结——进程的描述和进程的创建

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  3. 《Linux内核分析》第六周笔记 进程的描述和进程的创建

    进程的描述和进程的创建 一.进程的描述 1.进程描述符task_struct数据结构(一) 操作系统的三大功能:进程管理(核心).内存管理.文件系统. 进程控制块PCB——task_struct(进程 ...

  4. 20135327郭皓--Linux内核分析第六周 进程的描述和进程的创建

    进程的描述和进程的创建 一.进程的描述 操作系统三大功能: 进程管理 内存管理 文件系统 进程描述符task_struct数据结构 task _ struct:为了管理进程,内核必须对每个进程进行清晰 ...

  5. 20135337朱荟潼 Linux第六周学习总结——进程的描述和进程的创建

    朱荟潼 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课http://mooc.study.163.com/course/USTC 1000029000 第六周 进程的描述 ...

  6. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  7. 《Linux内核分析》 第六节 进程的描述和进程的创建

    <Linux内核分析> 第六节 进程的描述和进程的创建 20135307 张嘉琪 原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study ...

  8. linux内核分析第六周学习笔记

    LINUX内核分析第六周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...

  9. 20135239益西拉姆 Linux内核分析 进程的描述和进程的创建

    [益西拉姆 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 第六周 进程的描述 ...

随机推荐

  1. python进程-进阶

    进程同步(multiprocessing.Lock(锁机制).multiprocessing.Semaphore(信号量机制).multiprocessing.Event(事件机制)) 在计算机中,有 ...

  2. stl源码分析之list

    本文主要分析gcc4.8版本的stl list的源码实现,与vector的线性空间结构不同,list的节点是任意分散的,节点之间通过指针连接,好处是在任何位置插入删除元素都只需要常数时间,缺点是不能随 ...

  3. Javac提示不是内部或外部命令

    1.先去百度搜索"jdk下载"下载最新版jdk,并安装,安装目录不用去更改,直接默认就好,下载完了之后,双击打开安装,jdk安装完成后,会接着安装jre包,(jre和jdk是配对的 ...

  4. 教你thinkphp5怎么配置二级域名

    有些项目要将移动端和PC端分离开来,比如访问xxx.com,展示的是PC端的页面.而访问m.xxx.com,展示的是移动端的页面.thinkphp源码需要多多学习,这里记录一下知识点,顺便分享给需要的 ...

  5. 天马行空DevOps-Dev平台建设概述

    概述 DevOps(Development和Operations的组合词)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整合.它是一 ...

  6. c# 免费版pdf转word尝试

    链接:https://pan.baidu.com/s/1Dwuezo6YGe9CdlSyrwQyNg 密码:c81a 1.安装此程序 2.在安装文件的bin下拷贝dll: 3.代码引用 private ...

  7. Mac安装jee开发环境,webservice环境搭建

    一.下载安装包 jdk(去官网下载) eclipse (去官网下载) tomcat(官网有9.0了)http://tomcat.apache.org/download-80.cgi#8.0.32 下载 ...

  8. Alpha阶段敏捷冲刺 ADY8

    一.举行站立式例会 今天也没有拍照片,人不齐. 二.团队报告 1.昨日已完成的工作 (1)创建一个test,并且将图片导入进去使其可以显示. 2.今日计划完成的工作 完成收尾工作.实现代码的连接. 3 ...

  9. [转帖] 部分收费的Oracle JDK VS 完全免费的OpenJDK

    来源: http://www.flammulina.com/2018/10/28/%E9%83%A8%E5%88%86%E6%94%B6%E8%B4%B9%E7%9A%84oracle-jdk-vs- ...

  10. php伪静态配置

    配置虚拟主机和伪静态 1.开启Apache的rewrite模块 LoadModule rewrite_module modules/mod_rewrite.so 2.开启虚拟主机功能 # Virtua ...