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. IDEA 配置Junit4

    Junit4 主要用来执行java程序的单元测试: 1 安装junit4插件 因为我安装过了,没有安装的再输入框搜索,然后安装就行 2 选择默认使用Junit4 3 红框中的test去掉,变为“$en ...

  2. Nginx快速入门

    本文主要介绍nginx的基本配置和操作,并介绍了一些可以完成的简单任务. 假设您已经学习过并已经安装好了nginx服务器. 如果没有,请参阅安装nginx页面(http://www.yiibai.co ...

  3. leetcode28_C++实现strStr()函数

    实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...

  4. Paper Reading - Long-term Recurrent Convolutional Networks for Visual Recognition and Description ( CVPR 2015 )

    Link of the Paper: https://arxiv.org/abs/1411.4389 Main Points: A novel Recurrent Convolutional Arch ...

  5. Linux 发展史与vm安装linux centos 6.9

    操作系统 是一个人与计算机硬件的中介. Linux操作系统 开源代码的.自由传播的类Unix操作系系统软件: 多用户.多任务.多线程.多CPU的操作系统. 服务器端.嵌入式开发.个人pc桌面,服务器领 ...

  6. eclipse技巧-快捷键

    ctrl + 1,快速修复 ctrl + d, 快捷删除行 shift + Enter,快速移动光标到下一行 ctrl + F11,运行代码 alt + ↑/↓,快速移动行 ctrl + alt + ...

  7. USACO 1.2.2 Transformations 方块转换

    Description 一块N x N(1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案.写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式: 1:转90度 ...

  8. Summarize to the Power of Two(map+思维)

    A sequence a1,a2,…,ana1,a2,…,an is called good if, for each element aiai, there exists an element aj ...

  9. web.config详解(转载)

    该文为转载 原文地址:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.c ...

  10. 类的static成员变量和成员函数能被继承吗

    1.   父类的static变量和函数在派生类中依然可用,但是受访问性控制(比如,父类的private域中的就不可访问),而且对static变量来说,派生类和父类中的static变量是共用空间的,这点 ...