源代码阅读:
type.h:用于声明一些数据类型的简化名称,和声明页表指针的数据类型。
param.h:主要用于声明基本的一些常量,包括内核栈大小等。
memlayout.h:主要用于声明一些和内存与地址相关的常量与方法,包括虚拟内存转物理内存的方法以及物理内存转虚拟内存的方法等。
defs.h:声明在之后文件中要用到的函数。
x86.h:让c代码使用特殊的x86汇编的一些函数包括outb等,并声明trapframe。
asm.h:一些汇编上的宏定义
mmu.h:定义x86内存管理单元,包括控制寄存器CR上的不同位代表的含义。
elf.hELF:可执行文件的格式,包括ELF头的数据结构等。
vm.c:一些cpu虚拟内存管理的函数
proc.h:声明了CPU在内核中的数据结构表示struct cpu,进程在内核中的数据结构struct proc,上下文在内核中的数据结构struct context。
swtch.S声明用于上下文切换的swtch函数,汇编语言生成
kalloc.c声明一些物理内存分配的函数,包括分配的kalloc()和用于free的kfree()。

Proc.c:
Ptable:进程索引表
Nextpid:进程的ID
Allocproc:分配进程的内核栈和一些寄存器,将进程状态UNUSED改写为EMBRYO
Userinit:第一个进程的初始化操作
Growproc:增加或者减少所占用的内存空间
Fork():创建进程
Exit():退出当前进程,并将其父进程唤醒
Wait();等待子进程退出的
scheduler():内核运行时用于进程调度的循环
sched():切换到内核的
yield():放弃cpu占用
sleep();换成SLEEPING状态,并通过chan标志进程
wakeup();唤醒chan上所有的进程
kill():杀死进程
procdump;向控制台上打印当前进程状态的

(一) 什么是进程,什么是线程?操作系统的资源分配单位和调度单位分别是什么?XV6 中的
进程和线程分别是什么,都实现了吗?
答案:
(1)什么是进程:
1:操作系统由单道处理转向多道处理,传统的静态程序已经不能描述执行的并发性,所以由动态的进程对多道并发进行描述。
2:进程是程序,数据,程序控制块的集合
(2)什么是线程:
(3):进程占用空间多,切换时空消耗大。而为了降低时空消耗,引入了线程
引入线程前:资源分配单位和调度为进程
引入线程后:资源分配的单位是进程,调度的单位是线程
(4)XV6中只实现了进程proc,具体内容在proc.c中

(二) 进程管理的数据结构是什么?在 Windows,Linux,XV6 中分别叫什么名字?其中包含哪些内容?操作系统是如何进行管理进程管理数据结构的?它们是如何初始化的?
(1):进程管理的数据结构是进程控制块。
(2):Linux:task_struct
Windows:EPROCESS、KPROCESS、PEB
XV6:proc .h,proc.c
(3):包含 进程描述信息,进程控制信息,所拥有的资源和使用情况,CPU现场信息
1:Linux下为/include/linux/sched.h内部的struct task_struct,其中包括管理进程所需的各种信息。创建一个新进程时,系统在内存中申请一个空的task_struct ,并填入所需信息。同时将指向该结构的指针填入到task[]数组中。
2:Windows下拥有两个相关的对象,EPROCESS(执行体进程对象) KPROCESS(内核进程对象 )其中KPROCESS又称为PCB
EPEOCESS位于内核层之上它侧重于提供各种管理策略,同时为上层应用程序提供基本的功能接口。所以,在执行体层的进程和线程数据结构中,有些成员直接对应于上层应用程序中所看到的功能实体。
KPROCESS结构体位于内核层,存储着进程的必要信息

3:XV6下在proc .h内声明,包括进程 ID ,进程状态 ,父进程,context,cpu记录了内存地址和栈指针等
xv6的PCB就是proc.h中的proc结构体。其内容包括:
uint sz:进程的内存空间大小。
pde_t* pgdir:进程的页表。
char *kstack:进程的内核栈指针
enum procstate state:进程的状态(包括六种UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE)
int pid:进程的pid
struct proc *parent:进程的父进程指针。
struct trapframe *tf:位于x86.h,是中断进程后,需要恢复进程继续执行所保存的寄存器内容。
struct context *context:切换进程所需要保存的进程状态。切换进程需要维护的寄存器内容,定义在proc.h中。
void *chan:不为0时,保存该进程睡眠时的队列。
int killed:不为0时,则该进程被杀死。
struct file *ofile[NOFILE]:打开文件的组。
struct inode *cwd:进程当前的目录。
char name[16]:进程名。
(4):Xv6通过数据结构ptable对进程进行管理,代码如下:
struct {
struct spinlock lock;
struct proc proc[NPROC];
} ptable;
(5):Xv6的初始化操作:
1:第一个进程初始化:自举程序bootmain.c,调用主方法main.c,调用proc.c中的userinit()建立
2:第一个用户进程(分配了一个物理页,并将这个物理地址页映射到虚拟地址为0处,将原来的加载到物理地址为0处的initcode.S的代码加载到这个虚拟地址对应的物理页中。另外还设置进程的trapframe,以便能从内核态返回到用户态)
3:之后的进程初始化:调用fork()
4:无论是userinit()还是fork()都会调用allocproc()函数
5:allocproc的工作是在页表中分配一个槽(即结构体 struct proc),并初始化进程的状态,为其内核线程的运行做准备。简而言之,即设置好一个特别准备的内核栈和一系列内核寄存器,并将进程状态由UNUSED改写为EMBRYO

(三) 进程有哪些状态?请画出 XV6 的进程状态转化图。在 Linux,XV6 中,进程的状态分别 包括哪些?你认为操作系统的设计者为什么会有这样的设计思路?
(1):进程状态分别有:UNUSED,EMBRYO,RUNNABLE,RUNNING,SLEEPING,ZOMBIE
1:UNUSED:进程的初始化状态(enum枚举特性决定)
2:fork()或者userinit()中调用allocproc()即分配内核栈后改为EMBRYO
3:fork()或者userinit()进行一系列初始化操作后改为RUNNABLE
4:scheduler()会一直执行选择进程改为RUNNING,进程调用yield()改为RUNNABLE, 调用sleep()改为SLEEPING,而wakeup()由SLEEPING改为RUNNABLE
5:程序调用exit()和wait()会将其变为ZOMBIE

(2):Linux进程状态:创建,就绪,执行,阻塞,就绪挂起,阻塞挂起,结束

(3):提高CPU的利用率,增加并发能力

(四) 如何启动多进程(创建子进程)?如何调度多进程?调度算法有哪些?操作系统为何要 限制一个 CPU 最大支持的进程数?XV6 中的最大进程数是多少?如何执行进程的切换?什么是进程上下文?多进程和多 CPU 有什么关系?

(1):利用操作系统创建或者父进程创建,在xv6中,第一个进程是由Userinit()创建初始化,之后通过fork()创建初始化

(2):利用调度算法进行调度

(3):先来先服务,短作业先服务,时间片轮转发,优先级调度法,多级反馈轮转法,高响应比优先法

(4):一是考虑内存空间,进程数量过多占用大量内存 二是增加了缺页中断的可能性,会导致cpu不断的执行页面换入换出,浪费大量时间

(5):XV6的最大进程数见param.h文件中的#define NPROC 64,最大64;
#define NPROC 64 // maximum number of processes

(6):切换上下文:
1:当前进程通过调用yield()(可能是时间片用完),进行进程切换。yield函数调用sched函数,sched函数启动switch函数完成进程切换,而switch又会触发scheduler(void),scheduler(void)中会选择一个进程切换上下文,仍调用swtch(&cpu->scheduler, proc->context);
2:整个流程是这样的:yield->sched->switch->scheduler->switch
3:其中switch的函数原型void swtch(struct context **old, struct context *new);
4:它的工作主要包括:1. 保存当前(old)进程的上下文。 2. 加载新进程(new)的上下文到机器寄存器中。可以理解为是汇编实现

(7):进程运行时,其硬件状态保存在CPU 上的寄存器中,寄存器:程序计数器、程序状态寄存器、栈指针、通用寄存器、其他控制寄存器的值。进程不运行时,这些寄存器的值保存在PCB 中。将CPU 硬件状态从一个进程换到另一个进程的过程称为
上下文切换

(8):没有必然联系。一个CPU在某一时刻只能运行一个进程,宏观上并行,微观上串行。而多个CPU可以同时运行多个程序

(五) 内核态进程是什么?用户态进程是什么?它们有什么区别?
(1):系统分为内核态和用户态。在内核里产生的进程称为内核级进程,在用户态上产生的进程称为用户态进程。
(2)区别:
1)运行在不同的系统状态,用户态进程执行在用户态,内核态进程执行在内核态
2)进入方式不同,用户态进程可直接进入,内核态必须通过运行系统调用命令
3)返回方式不同,用户态进程直接返回,内核态进程有重新调度过程
4)内核态进程优先级要高于用户态进程,并且内核态进程特权级别最高,它可以执行系统级别的代码
联系:
用户级进程和内核级进程存在一对一,多对一,多对多的关系

(六) 首先看一个简略的进程在内存中的布局

再看一个详细的部分

在内存中分为五部分:
(1)代码区(Code segment):存放程序的二进制代码文件
(2)常量区(Constant segment):所有常量均存放在常量区。程序结束后由OS释放通常是字符串常量
(3)全局数据区(Global data segment):全局变量和静态数据,函数内部的静态局部变量。程序结束有OS释放
(4)堆区(Heap segment):new,malloc产生的动态数据。由程序员分配和释放 一般一个new就要对应一个delete
有时候堆区又分为 自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
(5)栈区(Stack segment):局部变量,函数参数。由编译器自动分配和释放
一个例子,大概介绍各个常量和变量的对应区关系
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = “123”; 栈
char *p2 = “abcdefg”;abcdefg\0在常量区,p3在栈上。
char *p3; 栈
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, “123456”); 123456\0放在常量区,编译器可能会将它与2所指向的"abcdefg"
优化成一个地方。
}
栈和堆的区别
(1)申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:堆中空闲内存地址是以链表方式进行存储的。当需要申请分配时,遍历链表寻找第一个大于所申请空间的堆结点,将此节点的空间分配给程序并且记录本次分配的大小,以便于之后delete程序释放内存空间。
若找到的堆节点大于申请的大小,系统会将多余的部分重新放入空闲链表

(2)申请大小的限度
栈:在Windows下,栈是向低地址扩展的数据结构, 是一块连续的内存的区域。栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,用链表来存储,是不连续的内存区域。而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较

(3)申请效率的比较:
栈:系统自动分配,速度较快。但程序员是无法控制的
堆:由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.

(4)堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的,会进入全局数据区当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

参考资源:
https://www.jianshu.com/p/e01680c00de4
https://blog.csdn.net/zhanglei8893/article/details/6101076
https://blog.csdn.net/qq_36347375/article/details/91354349
https://www.cnblogs.com/LittleHann/p/3454748.html
https://www.cnblogs.com/itzxy/p/9293677.html

高级操作系统——XV6进程管理相关推荐

  1. 【操作系统】进程管理(二)

    [操作系统]进程管理(二) 一.前言 二.进程的基本概念 2.1 程序的顺序执行 2.2 程序的并发执行 2.3 进程的特征 2.4 进程的状态 2.5 进程控制块 三.进程控制 3.1 进程的创建 ...

  2. 【操作系统】进程管理(五)—— 信号量机制

    [操作系统]进程管理(五)-- 信号量机制 前言 一.信号量机制 信号量机制--整型信号量 信号量机制--记录型信号量 二.用信号量机制实现进程互斥.同步.前驱关系 信号量机制实现进程互斥 信号量机制 ...

  3. 操作系统笔记——进程管理

    操作系统笔记--进程管理 2. 进程管理 2.1 进程与线程 2.1.1 进程的引入 前趋图 程序的顺序执行 程序的并发执行 2.1.2 进程的定义及描述 进程的定义 进程的特征 进程和程序的关系 进 ...

  4. 操作系统之——进程管理:同步进程和进程互斥

    操作系统进程管理-同步和互斥 在看了操作系统关于进程管理中的同步互斥机制章节之后,甚是困惑,今天通过视频.网上博客资料学习之后,整理一下相关知识点. 进程管理 一.进程互斥 由于进程具有独立性和异步性 ...

  5. 操作系统之进程管理-翟一鸣-专题视频课程

    操作系统之进程管理-192人已学习 课程介绍         主要内容是程序的并发执行及进程的概念,进程的状态及其转换,进程的同步与互斥,进程通信与调度,进程死锁的概念及解决死锁的方法,线程的概念及其 ...

  6. 视频教程-操作系统之进程管理-操作系统

    操作系统之进程管理 1979年出生于甘肃省兰州市,2001年7月本科毕业于西北师范大学计算机科学与技术专业,同年于烟台大学计算机学院任教至今:期间于2006年获得上海交通大学软件工程硕士学位,现为学院 ...

  7. 操作系统之进程管理相关总结

    第三章 进程管理 1.1进程的概念 1.1.1为什么要引入进程 程序并发执行具有如下特征 间断性 失去封闭性 不可再现性 程序的并发可以总结为:一组在逻辑上相互独立的程序或程序段在执行过程中,其执行时 ...

  8. 操作系统之进程管理(上),研究再多高并发,都不如啃一下操作系统进程!!!...

    目录: 进程管理 程序运行过程 进程实体的组成 进程的组织 进程的状态与转换 进程控制 为什么需要原语? 原语的实现? 中断机制 进程通信 共享内存 管道通信 消息传递 小结 线程 三种线程模型 多对 ...

  9. 高级操作系统——XV6中断机制

    1. 什么是用户态和内核态?两者有何区别?什么是中断和系统调用?两者有何区别?计算机在运行时,是如何确定当前处于用户态还是内核态的? 用户态:运用非特权指令,在Linux中特权级为3级,Ring3,最 ...

  10. 操作系统02进程管理Process_Description_and_Control

    作业的基本概念:用户再一次计算过程中或一次事务处理过程中,要求计算机系统所做的工作的集合. 包含多个程序.多个数据.作业控制说明书 系统调用时操作系统提供给编程人员的唯一接口. 1.文件操作类: 2. ...

最新文章

  1. 项目: 推箱子图形化游戏 【C++ / C】
  2. 2021版IDEA用Maven创建web项目
  3. boost::hana::value_of用法的测试程序
  4. CSS3笔记之定位篇(二)z-index
  5. python中pillow库怎么使用_Python 图像库Pillow使用
  6. opencv-api draw
  7. [转载] python不允许使用关键字_Python中关键字global与nonlocal的区别
  8. 线性渐变和放射性渐变
  9. SynthMaster One波表合成器绿色版亲测有效
  10. 【SVM分类】基于布谷鸟算法优化支持向量机SVM实现数据分类附matlab代码
  11. RaspberrIPCam – Full HD IP Camera based on Raspberry Pi
  12. html采集插件如何用,火车采集器插件功能详解
  13. kali linux窗口变大,kali怎么把屏幕放大
  14. 微信公众号开发(一)服务器配置
  15. 儿童节活动需要的设计感海报
  16. NR-PRACH:prach格式以及时频域情况
  17. 注销计算机桌面的东西会没有么,电脑注销会删掉内容吗
  18. UGF游戏框架实例开发教程—FlappyBird(七)子弹发射与小鸟飞行功能的实现
  19. 图书馆共享计算机,图书馆资源共享中计算机网络技术的使用
  20. oracle--基本转换函数

热门文章

  1. 华为云计算HCIE学习笔记-FusionAccess
  2. Qt 5 下载与安装详解
  3. 精益标准工时软件VIOOVI:没有标准工时,别谈精益改善!
  4. c语言餐厅饭卡管理系统,饭卡管理系统
  5. 最新版本启动HBuilderX.exe时,被联想mcafee杀毒软件删除的解决方法
  6. eclipse安装svn插件时,Subclipse与Subversive的选择与区别
  7. eclipse 每次打开 提示 subversive svn connectors
  8. Android支持库AndroidX和support-v4、appcompat-v7的前世今生!
  9. NB-SVM strong linear baseline
  10. OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x000001faf3e50000