当前课程知识点:操作系统 >  第十二讲 进程控制 >  12.2 进程创建 >  12.2 进程创建

返回《操作系统》慕课在线视频课程列表

12.2 进程创建在线视频

12.2 进程创建

下一节:12.3 进程加载

返回《操作系统》慕课在线视频列表

12.2 进程创建课程教案、知识点、字幕

下面我们来介绍进程创建

那进程创建呢

是操作系统提供给

用户使用的一个系统调用

完成新进程的创建工作

在不同的操作系统当中呢

进程创建的API呢

或者叫系统调用接口呢

是不一样的

比如说在Windows里头

那它的创建接口叫CreateProcess

而且在这里头呢

它可以有多种不同的参数

比如说在这里创建的时候

关闭所有的文件描述符

在创建的时候指定子进程的环境

运行环境

好这些呢都是在Windows里的做法

而另外一大类呢

是在unix系统里头

也包括我们用到的linux系统

它是采用fork execute

两个系统调用来

完成新进程的创建的

那么在这里头呢

fork完成把一个进程复制成两个进程

这时候呢

它们所执行的程序是一样的

但是在这里头呢

它的变量有一个地方是不一样

就是进程的ID PID

父进程里的是

原来执行那个进程的ID

子进程呢

是分配给它的一个新的ID

好完成这个复制之后

接下来由加载execute

把一个新的程序加载到

内存当中重写当前进程

也就是这里新创建子进程

好这时候呢它的进程ID呢

是没有发生改变的

好等这个系统调用返回的时候

那我们这个就变成是两个进程

并且第二个进程呢我已经变成

一个新的程序在运行了

那这是呢

新进程创建一个基本的做法

那这是一个示 例说明

我如何用fork和execute

来创建一个新的进程

执行一个新的映像

fork在这个地方完成复制

到这个地方回来的时候

这个系统调用返回时

那我们这个系统里呢

就已经有两个进程了

并且这两个进程当前指令指针呢

都指向fork完之后的这一行

好这一行接下来就说

你fork成两个之后同时往后走

一样的执行那有什么意义呢

实际上到这一步的时候呢

父进程和子进程的返回值是不一样的

子进程的返回值是零

好那执行红的这一段

如果父进程返回的是子进程的ID

那它就蹦过这一段

执行后面代码去了

好在这子进程里头呢

我再加一个execute

好这时候我可以

加载任何一个程序

指定它有多少个参数

这些参数分别是什么

这是它的基本的引用模式

好在这个引用模式当中呢

我们说fork是完成了

一个进程的子进程的创建

它的内存是完全复制的

它的CPU的状态是完全复制的

当然在这里呢

所谓的完全复制

是需要有加注解的

那这里呢

会有特殊一些寄存器有变化

那这时候以便于我们区别

到底父进程和子进程的ID的不一致

好这是呢这两个系统调用

这个系统调用它准确的区别

父进程返回子进程ID

子进程返回是零

好然后说我们在这里头

父进程这个fork

在进行子进程创建的时候

它的地址空间的复制

到底是怎么进行的

那我们说复制完了之后

它有一点小区别

那我们下面呢

通过一个图示 来说明这个

地址空间的复制过程

这是一个示例 程序

执行到S1 这一段代码的时候呢

整个进程还是一个

到fork的时候

这一句执行完就变成俩了

好然后这两个往下执行

由于返回值的不一致

子进程会进到这一段代码

父进程会进到下一段代码

好这两段都执行完了

如果说你在后面没有用execute

这时候再往后两个进程

可能直线代码也会一样

但是这时候

由于其中 的变量不一样

它俩的处理 结果也会不一样

好我们看一下

我把这个程序加载到内存

这是我们前面已经讲过的状态

好在这里执行的时候呢

执行到这一句的fork的时候

它做复制

复制一个跟它完全一样的

但是它俩有一个

不一样的就是这个地方

好那在这儿呢

这两个不一样

好不一样之后就会

导致后面的变量不一致

那它的执行内容

也就不一样了

这是呢 fork的地址空间复制的过程

那大家需要注意

这是一个完全的复制

但是有这两个的区别

好这两个区别

就导致后面它可以完全不一样

好然后我们说后面的加载呢

是用一个execute

用一个新的可执行文件

来替代当前的进程

那么在这个替代的过程当中呢

我们看到这是一个例子

红的这一段就是

我们加载新进程的代码

execute指定可执行的程序

有多少个参数

具体参数多少

那在这个执行的过程当中呢

我们看看它在操作系统里头的变化

fork进程创建起来之后

这个程序在执行的时候

操作系统内核里头呢

就给它维护了

一个相应的进程控制块

在这个进程控制块里头呢

有它的相关的ID和相关信息

那执行到fork它会是啥情况

fork执行的时候做了一个复制

复制完了之后给它一个新的ID

这个地方127

这变成128

然后其它都一样

然后接着往下执行

这一句的时候呢

父进程执行到这儿了

因为它不等于零

子进程执行进到这里头

然后执行这一句那是程序加载

那这个加载呢就会导致

把它地址空间里的代码都换掉

然后这个地方呢

加载的这个文件呢

也被换掉

好这样以来两个进程

就可以执行不同东西了

好那这是我们从代码的角度来说

而从完整地址空间来讲呢

这就是我们前面说

这地方的一点变化

我在这里头这是代码

然后上面是堆栈堆

好这是创建时候的情况

然后复制

两个一样

除了这个地方不一样

好那这时候呢我们这个地方

除了代码之外还有数据堆栈

这些都是一样的

然后我的加载什么呢

加载就把整个地址空间

内容全部换掉

除了保持这个ID继续一样

那这是我们这里fork和

execute的过程

那接下来我们用一个

稍微复杂一点的例子

让大家看一看这个

fork它在执行过程当中

这个复制到底是

保持了哪些是地方是一致的

哪些地方是变化的

这是一个例子

在这个例子当中呢有一个循环

我在循环内部呢有一个fork

假定说这个循环循环三次

大家想想一个循环

循环三次

这时候我会

这个fork会被执行几次

对于我们通常循环来说

循环三次

那这里头的fork函数

也会被执行三次

但是在这里头大家需要注意

fork一下的时候

我们整个就复制了一遍

这时候一个进程变成了俩

你再往后复制的时候

就是两个继续复制了

好正是由于这种原因

我们下面来看它到底有几个

好在这个进程里做的事情

比较简单

先上来做一个检查

我这个fork是否成功

不成功那直接就退出了

如果成功那这时候在

子进程里呢我打印一行信息

然后就开始等它的子进程结束

最后整个进程结束

那我们来看一下这个进程

在执行的时候它到底这个

进程的复制的过程是啥样子

好这是最初始的时候

这个进程开始执行的时候状态

假定它的进程ID是1166

好然后执行到循环体里头

第一次fork

fork就只有一个进程它在执行fork

fork完之后这一次变成俩了

那执行完是这个情况

好在子进程里头呢

它有一段代码说是

给出相应的一些提示信息

说自己的ID和父进程的ID

这是自己ID是1167

父进程的ID是1166

好然后进行第二次循环

第二次循环的时候呢

我们这个I实际上

已经复制了两份

在两个地址空间里头

所以它们的修改呢

是分别独立进行的

好那这时候这两个同时fork

那1166和1167分别进行fork

那这时候呢又出了两个新的进程

到现在有几个了

三个新进程

总共有四个进程了

好这个时候新创建出

来这两个进程呢

又各自给出一条提示信息

那这是1168 1170

它的父亲分别是1166和1167

好这时候第二次循环执行结束

然后那这时候我有四个进程

再做第三次循环的时候

这时候有几个再循环

四个好一二三四

它们同时进行fork

那又产生了四个

这新产生的四个呢

又在这儿呢又给出四行的提示

那从这儿看

我们循环第一遍的时候

一个变俩

第二遍 的时候两个变四个

第三遍 的时候四个变八个

那在这个过程当中

我们需要有一点注意

就是在这个地方

如果说按我刚才创建顺序

而我们新的PID的分配呢

是加一来给的

那你说好像你

这个顺序并不是顺序再加

这是为啥呢

实际上就相当于

我们创建的一个新的进程

它是新创建进程呢

放到就绪队列里面

那这时候由于调度算法的影响

所以新创建的这几个进程

并不是像刚才我们说的

严格按照我们刚才说的顺序在执行

第一步 只有一个创建出来

这个1166到1167没有问题

第二次执行的

那如果按照我们刚才说的

那就是父进程1168先算

好它创建了一个新进程

它创建完了之后

又放到就绪队列里头去

好实际上这个时候

这个进程呢它的执行

创建出来还执行之前

实际上已经进到这里的

第三次循环到1169

好那这样的话

创建顺序是它创建第一个

然后它创建第二个

它创建第三个是这个先完

然后是7创建70 71

然后是72 73

这样一个顺序

来执行新的进程了

所以这地方这个输出顺序呢

有可能会有些变化

好到这个地方呢

我们基本上说清楚了

从通常道理来讲fork

它是在怎么创建新的进程

这个创建行为有可能产生的变化

如果说我们在这里头

各个进程里头还有一些变量的话

这个变量的变化

搁到这一起

那这时候呢

你需要想清楚地方就会更多了

好那我们看实际的系统里头

它会是在怎么做

ucore里的fork是在怎么做

fork呢实际上我们就说

要进行准确的复制

并且给它一个新的ID

把它放到就绪队列里头

这是很粗的来说fork所做的功能

具体说起来呢

我们在fork里头呢

我们可以用这样两张图

来说明它的执行情况

左边这一个呢是说我们在系统里头

操作系统内核里头这是这个fork

fork它的实现调用了哪些函数

然后它是在什么情况下

哪些系统调用会产生进行fork

然后右边这个图呢

说明了fork它的内部的实现过程

它在这里头做哪样一些复制

和哪样一些改动

这是do_fork

ucore里实现进程创建的

最主要的函数

在这里它完成的功能是

分配进程控制块数据结构

然后创建它的内核堆栈

设置它的地址空间

那这时候设置地址空间呢

对于创建内核线程来说

它就是共享或者说复制

那创建独立的新的用户进程呢

那它就是复制

然后修改子进程的状态

变成运行状态

那这个函数呢

实际上我们可以看到

它在里头呢做的最主要的工作

我们对于创建来说

可以看到它的调用关系

在这张图当中这是do_fork

我们跟它相关的系统调用呢

有各种平台的fork clone

这些系统调用呢

最后都会转到do_fork

do_fork里做的主要的工作呢

我们从这里可以大致见到

说我进行相应的一些复制

这里头进行的几个复制

我们关心的主要的是copy memory

然后copy thread

这是我们看到的

跟它相关的最主要的数据结构

然后在这里头

在这个函数的实现当中

我们看到它的时间很长

我们转换成它的流程图这样的话

可以比较简洁的看到它的实现

那么在这个do_fork的实现当中

我们看到的最主要的函数呢

是在这里头

这是它的进程控制块的

相关信息的填写

比如说在这里头我们看到

它填的它的父进程

就是当前创建的这个进程在这儿

然后我们还关心一个新进程

在进行一系列的判断之后

我们看到的最主要的一件事情

那在这里呢

我们要去设置它的进程标识

那在这儿呢

我们就是创建了进程之后

给它设置相应的标识

在这个地方

好有了这些之后呢

我们一个进程就算是创建完了

这是关于的fork的ucore实现

好再有了fork的实现的环节之后

我们在系统里创建了哪些进程呢

比如说我系统起来的时候

第一个进程是啥样的

第一个线程是啥样的

好那我们在这儿呢

对这些做一个简要的说明

首先我们要说的是空闲进程

也就是说我们操作系统

它通常情况下执行用户的代码

如果用户没代码

用户的进程都执行完了

系统没有新的任务要执行了

这时候系统处于什么状态

那我们说处于暂停的状态

但实际上这时候暂停

CPU并没有完全停下来

它还是在执行指令

这执行是哪的指令呢

通常情况下我们就是

让它来执行空闲进程的处理

好空闲进程的创建是怎么来做呢

它是在我们的初始化文件里头

那proc_init

在这个函数里进行的

那它怎么做呢

它这里呢通过alloc_proc

这个函数来完成相应的创建过程

首先给它分配所需要的资源

比如说这函数会调用kmalloc

分配存储资源

分配完相应的资源之后呢

对它进程控制块进行初始化

填入它的一些相关信息

这是造出来的进程控制块

好然后呢

对这个进程呢

再在这个proc_init进行

完成剩下的部分的初始化

初始化之后放在就绪队列里头

没有其它进程的时候

那它是优先级最低的

然后就让它来执行

这是空闲进程

接下来我们看空闲进程的创建

空闲进程的创建呢

它首先是从kern_init()这个地方

这个函数呢开始内核的初始化

这个我们在前面的实验当中呢

已经多次看过这个函数了

其中有一个proc_init()

这是页表的初始化

我们找到它的定义

那这是它的页表的初始化

好首先在这里呢

它创建的第一个就是idle

那在这儿

然后创建的第二个呢

是用来执行init main这个函数

那我们看在这里头

首先是idle的创建

idle proc的创建

这一行是它最主要的工作

也就用alloc proc这个函数

来创建idle proc的相关信息

那这个函数呢我们对应过来

我们查看它的定义

这时候你会看到

它主要的工作是在这里头

对进程控制块的数据结构

进行初始化的设置

好完成这些设置之后呢

那我们一个进程的初始化呢

就基本上有了

然后这是设置这个进程的状态

另外一个呢是我们的初始化进程

那在这儿呢

用的是kernel_thread

这个创建函数来创建一个线程

执行init_main

作为它的内核函数

那这里头我们看它的实现

我们还是以它的调用图的形式来看

好我们看到在这里头

从我们这个地方initial

过来到这个地方

它在这里最后绕到哪去了

我们从这儿可以看到

最后绕到do_fork上去了

所以在这儿呢

创建内核线程和创建用户态进程

它的最后的实现呢

都在这个do_fork里头

好那么它们的区别在于

复制的时候这个地方的参数

是会不一样的

好我们再来看这是我创建完之后

第一个init_main()

好这是相应的创建的工作

就是我们用户态进程初始化之前

先创建了一个内核线程

这个内核线程呢

就是我们这里的initproc

这个也是在proc_init里头来创建的

在这里头怎么做呢

是通过kernel thread

这个函数来实现的

那我们说kernel thread

也是会调用do fork

和我们线程和进程都用一个

函数在ucore里来实现

但这时候它俩实现的时候

那进程创建和线程创建

我们说不是不一样嘛

实际上这时候不一样

是靠它里参数来区别的

这个过来的时候呢

它的地址空间是共享的

然后在这里头呢

拷贝现场所需要的信息就够了

比如说这里最主要一个

就是创建它的内核堆栈

好分配它相应的资源

然后在这里呢

初始化这个进程的进程控制块

然后在这里呢初始化它的内核堆栈

这地方没有拷贝了

那它的堆栈从哪来

它得新创建一个堆栈

好然后建立起它的内存的共享

也就说它和其它的内核线程

共享同一个内核地址空间

然后把它放到就绪队列当中

然后等到它下一次调度的时候

那调度它开始执行

那我们就可以创建

第一个用户态的进程了

我们刚才说的init proc

这一个函数呢实际上我们也是在

也从这个proc init这个函数开始来看

那到这儿来之后呢

我们有一个附值在这儿

我刚才创建的这个函数到这个地方

它把它这个地方创建了一个新的

它执行的函数是谁

然后它的ID

最后把它标识呢

设置成在这个地方

这一行最后给它附值为init proc

这是我们创建的第一个内核函数

它所执行的函数就是这个init proc

好在这里头呢

它执行的相关的操作是在这里

我们进行了相应的设置

好那在关于创建呢

我们还需要讨论一个问题是

fork的开销

那我们知道fork任务呢

是复制父进程的地址空间

内存和它的寄存器的状态

那这个复制的地址空间呢

通常情况下量是不小的

它的开销是非常大的

那我们开销大呢

我要创建这个东西

我必须干这个事

但实际上我们在这里

有这样一种情况

我们在fork完之后

马上会执行加载

这个加载呢

会把你刚才创建内容

复制内容又给覆盖掉

所以实际上在大多数情况下

你刚才这个复制都是没有必要的

没起到任何的作用

所以在这儿呢

这个开销呢

实际上是我们可以节约的

这种节约呢

就在Windows做法

它通过一个系统调用

用来完成创建和加载

那这时候呢

我们说在Unix里头呢

早的时候也有一种做法叫vfork

它是在创建的时候

不进行复制

等到你在用的时候

那再直接进行加载

那这个复制就省掉了

这种呢就称之为叫轻量级fork

而我们现在的系统里呢

通常都支持写时复制技术

那这样的话

任何一个进程创建的时候

都是在你后面要用的时候

它才延迟过来进行复制

那如果说

你在这里头直接就是覆盖

那这个地方这个复制它就不进行了

所以在这儿呢

我们这个地方这个开销呢

也是可以节约下来的

好这是关于fork的实现

操作系统课程列表:

第零讲 在线教学环境准备

-0.1 Piazza讨论区

--piazza访问和使用

--html

-0.2 在线实验平台

--实验平台使用帮助

--平台使用帮助

--Gitlab使用帮助

--IBM内部账号初始化

-0.2在线实验平台

--Raw HTML

第一讲 操作系统概述

-1.1 课程概述

--视频

-第一讲 操作系统概述--练习

-1.2 教学安排

--视频

-1.3 什么是操作系统

--Video

-1.4 为什么学习操作系统,如何学习操作系统

--Video

-1.5 操作系统实例

--视频

-1.6 操作系统的演变

--视频

-1.7 操作系统结构

--视频

第二讲 实验零 操作系统实验环境准备

-2.1 前言和国内外现状

--2.1 前言和国内外现状

-2.2 OS实验目标

--2.2 OS实验目标

-2.3 8个OS实验概述

--2.3 8个OS实验概述

-2.4 实验环境搭建

--2.4 实验环境搭建

-2.5 x86-32硬件介绍

--2.5 x86-32硬件介绍

-2.6 ucore部分编程技巧

--2.6 ucore部分编程技巧

-2.7 演示实验操作过程

--2.7 演示实验操作过程

--Q6

--Q7

--Q10

第三讲 启动、中断、异常和系统调用

-3.1 BIOS

--3.1 BIOS

-3.2 系统启动流程

--3.2 系统启动流程

-3.3 中断、异常和系统调用比较

--3.3 中断、异常和系统调用比较

-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较

-3.4 系统调用

--3.4 系统调用

-第三讲 启动、中断、异常和系统调用--3.4 系统调用

-3.5 系统调用示例

--3.5 系统调用示例

-3.6 ucore+系统调用代码

--3.6 ucore+系统调用代码

第四讲 实验一 bootloader启动ucore os

-4.1 启动顺序

--4.1 启动顺序

-4.2 C函数调用的实现

--4.2 C函数调用的实现

-4.3 GCC内联汇编

--4.3 GCC内联汇编

-4.4 x86中断处理过程

--4.4 x86中断处理过程

-4.5 练习一

--4.5 练习一

-4.6 练习二

--4.6 练习二

-4.7 练习三

--4.7 练习三

-4.8 练习四 练习五

--4.8 练习四练习五

-4.9 练习六

--4.9 练习六

第五讲 物理内存管理: 连续内存分配

-5.1 计算机体系结构和内存层次

--5.1 计算机体系结构和内存层次

-5.2 地址空间和地址生成

--5.2 地址空间和地址生成

-5.3 连续内存分配

--5.3 连续内存分配

-5.4 碎片整理

--5.4 碎片整理

-5.5 伙伴系统

--5.5 伙伴系统

-第五讲 物理内存管理: 连续内存分配--5.6 练习

第六讲 物理内存管理: 非连续内存分配

-6.1 非连续内存分配的需求背景

--6.1 非连续内存分配的需求背景

-6.2 段式存储管理

-- 6.2 段式存储管理

-6.3 页式存储管理

--6.3 页式存储管理

-6.4 页表概述

--6.4 页表概述

-6.5 快表和多级页表

--6.5 快表和多级页表

-6.6 反置页表

--6.6 反置页表

-6.7 段页式存储管理

--6.7 段页式存储管理

-第六讲 物理内存管理: 非连续内存分配--6.8 练习

第七讲 实验二 物理内存管理

-7.1 了解x86保护模式中的特权级

--7.1 了解x86保护模式中的特权级

-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级

-7.2 了解特权级切换过程

--7.2 了解特权级切换过程

-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程

-7.3 了解段/页表

--7.3 了解段/页表

-第七讲 实验二 物理内存管理--7.3 了解段/页表

-7.4 了解UCORE建立段/页表

--7.4 了解ucore建立段/页表

-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表

-7.5 演示lab2实验环节

--7.5 演示lab2实验环节

第八讲 虚拟存储概念

-8.1 虚拟存储的需求背景

--8.1 虚拟存储的需求背景

-8.2 覆盖和交换

--8.2 覆盖和交换

-8.3 局部性原理

--8.3 局部性原理

-8.4 虚拟存储概念

--8.4 虚拟存储概念

-8.5 虚拟页式存储

--8.5 虚拟页式存储

-8.6 缺页异常

--8.6 缺页异常

第九讲 页面置换算法

-9.1 页面置换算法的概念

--9.1 页面置换算法的概念

-9.2 最优算法、先进先出算法和最近最久未使用算法

--9.2 最优算法、先进先出算法和最近最久未使用算法

-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法

-9.3 时钟置换算法和最不常用算法

--9.3 时钟置换算法和最不常用算法

-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法

-9.4 Belady现象和局部置换算法比较

--9.4 Belady现象和局部置换算法比较

-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较

-9.5 工作集置换算法

--9.5 工作集置换算法

-第九讲 页面置换算法--9.5 工作集置换算法

-9.6 缺页率置换算法

--9.6 缺页率置换算法

-第九讲 页面置换算法--9.6 缺页率置换算法

-9.7 抖动和负载控制

--9.7 抖动和负载控制

第十讲 实验三 虚拟内存管理

-10.1 实验目标:虚存管理

--10.1 实验目标:虚存管理

-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理

-10.2 回顾历史和了解当下

-- 10.2 回顾历史和了解当下

-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下

-10.3 处理流程、关键数据结构和功能

--10.3 处理流程、关键数据结构和功能

-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能

-10.4 页访问异常

--10.4 页访问异常

-第十讲 实验三 虚拟内存管理--10.4 页访问异常

-10.5 页换入换出机制

--10.5 页换入换出机制

-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制

第十一讲 进程和线程

-11.1 进程的概念

--11.1 进程的概念

-第十一讲 进程和线程--11.1 进程的概念

-11.2 进程控制块

--11.2 进程控制块

-第十一讲 进程和线程--11.2 进程控制块

-11.3 进程状态

--11.3 进程状态

-第十一讲 进程和线程--11.3 进程状态

-11.4 三状态进程模型

--11.4 三状态进程模型

-11.5 挂起进程模型

--11.5 挂起进程模型

-第十一讲 进程和线程--11.5 挂起进程模型

-11.6 线程的概念

--11.6 线程的概念

-第十一讲 进程和线程--11.6 线程的概念

-11.7 用户线程

--11.7 用户线程

-第十一讲 进程和线程--11.7 用户线程

-11.8 内核线程

--11.8 内核线程

-第十一讲 进程和线程--11.8 内核线程

第十二讲 进程控制

-12.1 进程切换

--12.1 进程切换

-第十二讲 进程控制--12.1 进程切换

-12.2 进程创建

--12.2 进程创建

-第十二讲 进程控制--12.2 进程创建

-12.3 进程加载

--12.3 进程加载

-第十二讲 进程控制--12.3 进程加载

-12.4 进程等待与退出

--12.4 进程等待与退出

-第十二讲 进程控制--12.4 进程等待与退出

第十三讲 实验四 内核线程管理

-13.1 总体介绍

--13.1 总体介绍

-13.2 关键数据结构

--13.2 关键数据结构

-13.3 执行流程

--13.3 执行流程

-13.4 实际操作

--13.4 实际操作

第十四讲 实验五 用户进程管理

-14.1 总体介绍

--14.1 总体介绍

-14.2 进程的内存布局

--14.2 进程的内存布局

-14.3 执行ELF格式的二进制代码-do_execve的实现

--14.3 执行ELF格式的二进制代码-do_execve的实现

-14.4 执行ELF格式的二进制代码-load_icode的实现

--14.4 执行ELF格式的二进制代码-load_icode的实现

-14.5 进程复制

--14.5 进程复制

-14.6 内存管理的copy-on-write机制

--14.6 内存管理的copy-on-write机制

第十五讲 处理机调度

-15.1 处理机调度概念

--15.1 处理机调度概念

-第十五讲 处理机调度--15.1 处理机调度概念

-15.2 调度准则

--15.2 调度准则

-15.3 先来先服务、短进程优先和最高响应比优先调度算法

--15.3 先来先服务、短进程优先和最高响应比优先调度算法

-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法

-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架

--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架

-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc

-15.5 实时调度和多处理器调度

--15.5 实时调度和多处理器调度

-第十五讲 处理机调度--15.5 实时调度和多处理器调度

-15.6 优先级反置

--15.6 优先级反置

-第十五讲 处理机调度--15.6 优先级反置

第十六讲 实验六 调度器

-16.1 总体介绍和调度过程

--16.1 总体介绍和调度过程

-16.2 调度算法支撑框架

--16.2 调度算法支撑框架

-16.3 时间片轮转调度算法

--16.3 时间片轮转调度算法

-16.4 Stride调度算法

--16.4 Stride调度算法

第十七讲 同步互斥

-17.1 背景

--17.1 背景

-17.2 现实生活中的同步问题

--17.2 现实生活中的同步问题

-第十七讲 同步互斥--17.2 现实生活中的同步问题

-17.3 临界区和禁用硬件中断同步方法

--17.3 临界区和禁用硬件中断同步方法

-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法

-17.4 基于软件的同步方法

--17.4 基于软件的同步方法

-第十七讲 同步互斥--17.4 基于软件的同步方法

-17.5 高级抽象的同步方法

--17.5 高级抽象的同步方法

-第十七讲 同步互斥--17.5 高级抽象的同步方法

第十八讲 信号量与管程

-18.1 信号量

--18.1 信号量

-第十八讲 信号量与管程--18.1 信号量

-18.2 信号量使用

--18.2 信号量使用

-第十八讲 信号量与管程--18.2 信号量使用

-18.3 管程

--18.3 管程

-第十八讲 信号量与管程--18.3 管程

-18.4 哲学家就餐问题

--18.4 哲学家就餐问题

-18.5 读者-写者问题

--18.5 读者-写者问题

第十九讲 实验七 同步互斥

-19.1 总体介绍

--19.1 总体介绍

-19.2 底层支撑

--19.2 底层支撑

-第十九讲 实验七 同步互斥--19.2 底层支撑

-19.3 信号量设计实现

--19.3 信号量设计实现

-第十九讲 实验七 同步互斥--19.3 信号量设计实现

-19.4 管程和条件变量设计实现

--19.4 管程和条件变量设计实现

-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现

-19.5 哲学家就餐问题

--19.5 哲学家就餐问题

第二十讲 死锁和进程通信

-20.1 死锁概念

--20.1 死锁概念

-第二十讲 死锁和进程通信--20.1 死锁概念

-20.2 死锁处理方法

--20.2 死锁处理方法

-第二十讲 死锁和进程通信--20.2 死锁处理方法

-20.3 银行家算法

--20.3 银行家算法

-第二十讲 死锁和进程通信--20.3 银行家算法

-20.4 死锁检测

--20.4 死锁检测

-第二十讲 死锁和进程通信--20.4 死锁检测

-20.5 进程通信概念

--20.5 进程通信概念

-第二十讲 死锁和进程通信--20.5 进程通信概念

-20.6 信号和管道

--20.6 信号和管道

-第二十讲 死锁和进程通信--20.6 信号和管道

-20.7 消息队列和共享内存

--20.7 消息队列和共享内存

-第二十讲 死锁和进程通信--20.7 消息队列和共享内存

第二十一讲 文件系统

-21.1 文件系统和文件

--21.1 文件系统和文件

-第二十一讲 文件系统--21.1 文件系统和文件

-21.2 文件描述符

--21.2 文件描述符

-第二十一讲 文件系统--21.2 文件描述符

-21.3 目录、文件别名和文件系统种类

--21.3 目录、文件别名和文件系统种类

-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类

-21.4 虚拟文件系统

--21.4 虚拟文件系统

-第二十一讲 文件系统--21.4 虚拟文件系统

-21.5 文件缓存和打开文件

--21.5 文件缓存和打开文件

-第二十一讲 文件系统--21.5 文件缓存和打开文件

-21.6 文件分配

--21.6 文件分配

-第二十一讲 文件系统--21.6 文件分配

-21.7 空闲空间管理和冗余磁盘阵列RAID

--21.7 空闲空间管理和冗余磁盘阵列RAID

-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID

第二十二讲 实验八 文件系统

-22.1 总体介绍

--22.1 总体介绍

-第二十二讲 实验八 文件系统--22.1 总体介绍

-22.2 ucore 文件系统架构

--22.2 ucore 文件系统架构

-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构

-22.3 Simple File System分析

--22.3 Simple File System分析

-第二十二讲 实验八 文件系统--22.3 Simple File System分析

-22.4 Virtual File System分析

--22.4 Virtual File System分析

-第二十二讲 实验八 文件系统--22.4 Virtual File System分

-22.5 I/O设备接口分析

--22.5 I/O设备接口分析

-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析

-22.6 执行流程分析

--22.6 执行流程分析

第二十三讲 I/O子系统

-23.1 I/O特点

--视频

-第二十三讲 I/O子系统--23.1 I/O特点

-23.2 I/O结构

--816C80A0F5E3B8809C33DC5901307461

-第二十三讲 I/O子系统--23.2 I/O结构

-23.3 I/O数据传输

--C58221E14388B9DB9C33DC5901307461

-第二十三讲 I/O子系统--23.3 I/O数据传输

-23.4 磁盘调度

--567A3F1FCBFB3F4C9C33DC5901307461

-第二十三讲 I/O子系统--23.4 磁盘调度

-23.5 磁盘缓存

--C327536B80D25CE79C33DC5901307461

-第二十三讲 I/O子系统--23.5 磁盘缓存

html

-html

--html

12.2 进程创建笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。