XV6源码阅读报告

2019-07-14 12:27发布

阅读XV6源码中,进程线程相关代码,并集体讨论解答下列议题:  1. 什么是进程,什么是线程?操作系统的资源分配单位和调度单位分别是什么?XV6 中的 进程和线程分别是什么,都实现了吗?  2. 进程管理的数据结构是什么?在 WindowsLinuxXV6 中分别叫什么名字?其中包含哪 些内容?操作系统是如何进行管理进程管理数据结构的?它们是如何初始化的?  3. 进程有哪些状态?请画出 XV6 的进程状态转化图。在 LinuxXV6 中,进程的状态分别包 括哪些?你认为操作系统的设计者为什么会有这样的设计思路?  4. 如何启动多进程(创建子进程)?如何调度多进程?调度算法有哪些?操作系统为何要 限制一个CPU最大支持的进程数?XV6中的最大进程数是多少?如何执行进程的切换? 什么是进程上下文?多进程和多 CPU 有什么关系?  5. 内核态进程是什么?用户态进程是什么?它们有什么区别?  6. 进程在内存中是如何布局的,进程的堆和栈有什么区别 7. 其他你认为有趣有价值的问题。   相关代码提示: 1. 基本头文件:  types.h  param.h  memlayout.h  defs.h  x86.h  asm.h  mmu.h  elf.h  2. 进程线程部分:  vm.c  proc.h  proc.c  swtch.S  kalloc.c  以及相关其他文件代码 1. 什么是进程,什么是线程?操作系统的资源分配单位和调度单位分别是什么? XV6中的 进程和线程分别是什么,都实现了吗?:进程是在多道程序系统出现以后,为了描述系统内部各业的活动规律而引进的概念。进程有3个基本状态,运行状态、就绪状态和等待状态(或称阻塞状态) ; 进程只能由父进程建立, 系统中所有的进程形成一种进程树的层次体系;挂起命令可有进程自己和其他进程发出,但 是解除挂起命令只能由其他进程发出。进程是具有独立功能的程序关于某个数据集合上的 一次运行活动,是系统进行资源分配和调度的独立单位。线程可称为轻量级的进程,是操作系统可以运行调度的最小单位。线程是进程内的一个相对独立的可执行的单元。若把进程称为任务的话,那么线程则是应用中的一个子任务的执行。不论操作系统中是否引入了线程,操作系统中资源分配的基本单位都是进程。如果操作系统没有引入线程那么进程就是调度的基本单位。线程并不独立拥有资源, 它仅仅分配了一些运 行必备的资源。一个进程中的多个线程共同分享进程中的资源。在引入了线程的操作系 统中,线程就变成了调度的基本单位,进程中的部分线程阻塞并不代表该线程被阻塞。xv6操作系统实现了一个 基于进程 (没有实现线程) 的简单进程管理机制。通过对proc.h文件的阅读了解到 xv6的进程中定义了一个context 结构 , 一个枚举类型proc_state定义了UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE 6种进程的状态 , proc 结构定义了进程控制块的内容 , cpu 结构定义了寄存器和栈指针。 2.进程管理的数据结构是什么?Windows , Linux , XV6中分别叫什么名字?其中包含哪些 内容?操作系统是如何进行管理进程管理数据结构的? 它们是如何初始化的? :进程管理的数据结构是进程控制块 (PCB )。在 Linux 中进程控制块的结构是由一个叫 task_struct的 数据构定义的, ask_struct存在 /include/ linux/sched.h, 其中包括管理进程所需的各种信息。在创建一个新进程时, 系统在内存中申请一个空的task_struct, 即空闲PCB , 并填入所需信息 。同时将指向该结构的指针填入到task[]数组中。当前处于运 行状态进程的 PCB 用指针数组current_set[]来指出。这是因为 Linux 支持多处理机系统,系统内可能存在多个同时运行的进程, current_set定义成指针数组 。Windows的进程由执 行体进程块EPROCESS表示 , EPROCESS 即执行体进程对象 。在 Windows , PCB 也称为内核进程块 KPROCESS (KPROCESS 即内核进程对象 ) EPOCESS KPROCESS 位于内核空间 , PEB 位于用户空间 。 XV6的进程控制块是 proc 类中的 proc 定义了进程 ID , 进程 状态 , 父进程, context 保存寄存器为核的上下文切换 , cpu 记录了内存地址和栈指针 等。XV6中通过get_raw_proc()对进程进行控制管理, get_raw_proc()方法可以创建一个新的进程并对进程进行初始化分配进程页表 和内核堆栈 。 3. 进程有哪些状态?请画出 XV6的进程状态转化图Linux , XV6, 进程的状态分别包括哪些? 你认为操作系统的设计者为什么会有这的设计思路?:XV6进程包括UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE6种状态即未使用态、初始态、等待、就绪态、运行态、僵尸态。状态转换图如下: 这样设计是为了实现多道程序的交叉运, 和方便设计各种进程调度算法。在时间片轮转调度算法中RUNNING 的程序在时间片到的时候就会转成RUNNABLE 同时让出 CUP。 而正在RUNNING 的程序如果遇到资源申请, 就会主动放弃 CPU 进入 SLEEPING 状态。但是 SLEEPING 状态的程序如果得到资源之后并不能马上进入RUNNING而是先进入就绪队列等待CUP调度。Linux 的进程状态可分为R (TASK_RUNNING), 可执行状态, S (TASK_INTERRUPTIBLE), 可中断 的睡眠状态, D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态, T (TASK_STOPPED or TASK_TRACED), 暂停状态或跟踪状态, Z (TASK_DEAD - EXIT_ZOMBIE), 退出状态 ,进程成为僵尸进程, X (TASK_DEAD - EXIT_DEAD), 退出状态 ,进程即将被销毁 。 4. 如何启动多进程(创建子进程) ?如何调度进程?调度算法有哪些?操作系统为何要限制一个 CPU 最大支持的进程数 ? XV6中的最大进程数是多少如何执行进程的切换?什么是进程上下文?多进程和多CPU有什么关系?:子进程都是由父进程创建的, 比如使用 fork()函数 。创建的过程为:1). 为子进程分配一个空闲的proc结构 (进程描述符)2). 赋予子进程唯一标识pid3). 以一次一页的方式复制父进程地址空间 (有什么问题? )4). 获得子进程继承的共享资源的指针, 如打开的文件和当前工作目录5). 子进程就绪,加入调度队列6). 对子进程返回标识符0;向父进程返回子进程pid处理机调度可分为三个层次:长程调度、中程调度、短程调度。长程调度 (作业调度或宏观调度 ) :创建新进程时是否进入当前活跃进程集合。中程调度 涉及进程在内外存间的交换, 从负载控制的角度, 把一些进程换出到外存上, 可 为其他进程的执行提供所需内存空间, 如需要再换入到内存。短程调度 (微观调度) :CPU 分配的角度, 需要经常选择就绪进程或线程进入运行状态 , 短程调度的时间尺度通常是毫秒级的。 由于短程调度算法的频繁使用, 要求在实现时做到 高效 。常见的调度算法有:先来先服务、优先级调度算法、短作业优先算法、最短剩余时间优先算法、时间片轮转算法、高响应比优先算法、多级反馈队列算法。XV6的最大进程数写在 param.h 文件中的 #define NPROC 64 属性中。可以看出XV6默认定义的最大进程数是64进程切换是一个进程让出处理器 , 由另一个进程占用处理器的过程。进程的切换是由进程 状态的变化引起的, 而进程状态的变化又与出现的事件有关。当有事件(中断或异常)发生时, 当前运行进程暂停,由操作系统处理出现相应事件。处理结束, 某些进程的状态会发生变化, 因此 ,要调整队列。之后,进程调度根据调度算法从就绪队列选一个进程占用CPU。这个进程 可能仍然是被中断的进程,也可能是另一个进程。进程的上下文包括当前进程的程序计数 PC和当前运行的CPU 中各个寄存器的内容。 当 进程切换和发生中断的时候这些信息要保存下来以便于下次运行时使用。多进程和多CPU 我理解他们的区别就是并发和并行的区别。多进程是并发执行, 就是在一个时间段内有多个进程在执行,但是在某个时间点上是只有一个进程执行。 5. 内核态进程是什么? 用户态进程是什么? 它们有什么区别?:多数系统将处理器工作状态划分为内核态和用户态 。前者一般指操作系统管理程序运 行的状态,具有较高的特权级别, 又称为特权态、系统态或管态; 后者一般指用户程序运行时的状态 , 具有较低的特权级别, 又称为普通态、目态。区分了用户态和内核态就是限定用户 什么操作可以做 , 什么操作不能让用户直接做。如果遇到不能让用户直接做的操作, 用户 就必须请求操作系统做系统调用 , 这样操作系统就会进入内核态进行系统操作。内核态的进程就是系统进入内核态之后进行系统操作所产生的进程。而用户态进程是用户通过请求操作而产生的进程。它们的主要区别有:1)  运行在不同的系统状态 , 用户态进程执行在用户态 ,内核态进程执行在内核态。2) 进入的方式不同用户态进程直接进入而内核态必须通过运行系统调用命令。 3) 返回方式不同, 用户态进程直接返回 ,内核态进程有重新调度过程。 4) 内核态进程优先级要高于用户态进程。并且内核态进程特权级别最高, 它可以执行系统级别的代码。 6. 进程在内存中是如何布局的,进程的堆和栈有什么区别?:内存分为内核空间和用户空间 , 内核空间一般运行操作系统程序而用户空间一般运行 用户程序。主要目的是对系统程序进行包含。进程在内存中包含堆、栈、数据段、代码段。 代码段 : 保存程序的执行码。在进程并发时, 代码段是共享的且只读的,在存储器中只需有一个副本。数据段此段又称为初始化数据段,它包含了程序中已初始化的全局变量、 全局静态变量、 局部静态变量 。程序执行前静态分配的内存空间,栈的大小可在编译时指定 , Linux 环境下默认为 8M。 栈段是存放程序执行时局部变量、函数调用信息、中断现场保留信息的空间。程序执行时,CPU 堆栈段指针会在栈顶根据执行情况进行上下移动。程序执行时, 按照程序需要动态分配的内存空间。malloc calloc realloc 函数分配的空间都在堆上分配。