第四章中央处理器教案.docx
- 文档编号:11002025
- 上传时间:2023-02-24
- 格式:DOCX
- 页数:45
- 大小:132.53KB
第四章中央处理器教案.docx
《第四章中央处理器教案.docx》由会员分享,可在线阅读,更多相关《第四章中央处理器教案.docx(45页珍藏版)》请在冰豆网上搜索。
第四章中央处理器教案
四川师范大学信息技术学院理工教研室张永来
任课老师:
张永来上课时间:
2013.8.1
课题
第4章进程管理
班级
2010级计算机科学与技术班
课时
4
学情分析
进程管理是学生接触到的操作系统基础原理中的第一部分,也是最重要的。
如何让学生学得不枯燥、学得不抽象是个值得思考的问题
教学目标
1理解进程、线程、PCB概念2理解并掌握进程的状态转换3理解并掌握进程的两种运行模式4重点理解并掌握终端技术5理解并掌握操作系统及Linux的进程控制功能6理解Shell命令的执行过程7理解并熟练掌握操作系统进程调度原理及Linux下的进程调度策略与过程8熟练掌握进程的互斥与同步的作用及其使用,知道Linux下的进程同步机制---信号量机制。
9掌握死锁的产生原因及避免方法。
10知道Linux的进程通信方式;掌握Linux的信号通信原理和管道通信原理11理解并掌握线程概念。
教学重点
进程、线程、PCB概念;进程的状态转换;进程控制;进程调度;进程的互斥与同步
教学难点
进程控制;进程调度;
重点、难点
解决办法
解决办法:
分析讨论法、讲解法
过程与方法
类比法、讨论法、分析法
教学过程
呈现
方式
设计
意图
引入新课:
操作系统一般只有一个处理器,现在大多也就两个,可我们计算机里面可能会运行很多软件,但我们用户看起来是这些软件同时在运行,这是怎么回事呢?
讲授新课
第4章进程管理
1)进程管理的功能:
跟踪和控制所有进程的活动,为它们分配和调度CPU,协调进程的运行步调
2)进程管理的目标:
最大限度地发挥CPU的处理能力,提高进程的运行效率
第4.1节进程
4.1.1程序的顺序执行与并发执行
1程序的顺序执行
1)什么叫顺序执行
程序的各操作步骤是依序执行的,程序与程序之间是串行执行的,就叫程序的顺序执行。
2)顺序执行是单道程序系统中程序的运行方式
3)顺序执行的特点:
(1)顺序性
(2)封闭性
(3)可再现性
4)缺点:
一个程序独占全部系统资源,系统资源利用率很低
2程序的并发执行
1)什么叫并发执行
程序的并发执行是指若干个程序或程序段同时存在于内存中运行
2)并发运行是多道程序系统(现代操作系统)中的基本特征
3)特点:
(1)间断性:
因竞争资源而间断,如轮流占用CPU
(2)没有封闭性:
(3)不可再现性
3并发执行的潜在问题
1)程序在并发执行时会导致执行结果的不可再现性,这是多道程序系统必须解决的问题。
2)举例见ppt或者教材page75
4.1.2进程的概念
1.进程
1)进程概念:
进程就是程序的一次运行过程
2)进程与程序的关联
程序是进程的一个组成部分,是进程的执行文本,而进程是程序的执行过程。
3)进程与程序的区别
A程序是静态的指令集合,可以永久存在
B进程是个动态的过程实体,动态地产生、发展和消失。
打比喻进行解释:
电影与胶片的关系:
胶片是静态的,是电影的放映素材。
而电影是动态的,一场电影就是胶片在放映机上的一次“运行”。
C进程与程序之间也不是一一对应的关系:
(1)一个进程可以顺序执行多个程序,如同一场电影可以连续播放多部胶片一样。
(2)一个程序可以对应多个进程,就像一本胶片可以放映多场电影一样。
举例:
vi,QQ
2.进程的特性
(1)动态性:
(2)并发性:
(3)独立性:
(4)异步性:
不可预知的进度
3.进程的基本状态
1)宏观上,所有进程同时运行
2)微观上,串行
3)进程的三个基本状态:
(1)就绪态:
分配到了除CPU之外的所有资源。
就绪态的进程放进就绪队列里
(2)运行态:
进程已经获得CPU,正在运行
(3)等待态:
等待某种资源或者事件发生而暂停执行。
等待态进程进入等待队列
4.进程状态的转换
4.1.3进程控制块
1.进程控制块
进程由程序、数据和进程控制块3部分组成。
进程控制块记录进程的所有信息,一个进程对应一个进程控制块,是进程的标志
2.进程控制块的内容
1)进程描述信息:
包括进程标识号PID、父进程和子进程的信息
2)进程控制和调度信息:
进程的当前状态、调度信息、记时信息等
3)资源信息:
资源包括该进程使用的存储器空间、打开的文件以及设备等
4)现场信息:
一般包括CPU的内部寄存器和系统堆栈。
用于进程切换和恢复
4.1.4进程的组织
管理进程就是管理进程的PCB。
所有的PCB都存放在内存中,通常采用的组织结构有数组、索引和链表3种方式。
数组方式:
效率低,如查找某个PCB时需要扫描全表
索引方式是通过在PCB数组上设置索引表或散列表,以加快访问速度。
链表方式是将PCB链接起来,构成链式队列或链表
4.1.5Linux系统中的进程
进程也称为任务(task),两者一致
1. Linux进程的状态
5种基本状态:
运行、就绪、睡眠(分为可中断的与不可中断的)、暂停和僵死
状态转换图
Linux将这些基本状态归结为4种:
(1)可执行态(runnable):
可执行态包含运行和就绪两种状态
(2)睡眠态(sleeping):
即等待态。
睡眠态又细分为可中断的(interruptible)和不可中断的(uninterruptible)两种
(3)暂停态(stopped):
暂停态的进程一般都是由运行态转换而来,等待某种特殊处理。
比如调试跟踪的程序、断点
(4)僵死态(zombie):
进程运行结束或因某些原因被终止时,它将释放除PCB外的所有资源。
这种占有PCB但已经无法运行的进程就处于僵死状态。
2. Linux进程的状态转换过程
如上图
3. Linux的进程控制块
Linux系统的PCB用一个称为task_struct的结构体来描述。
一个进程对应一个task_struct结构,填入进程的控制信息,包括:
(1)进程标识号(PID):
(2)用户标识(UID)和组标识(GID):
(3)链接信息:
用指针的方式记录进程的父进程、兄弟进程以及子进程的位置(即PCB的地址)。
(4)状态:
进程当前的状态。
(5)调度信息:
与系统调度相关的信息,包括优先级、时间片和调度策略。
(6)记时信息:
包括时间和定时器。
时间记录进程建立的时间以及进程占用CPU的时间统计
(7)通信信息:
记录有关进程间信号量通信及信号通信的信息。
(8)退出码:
记录进程运行结束后的退出状态,供父进程查询用。
(9)文件系统信息:
包括根目录、当前目录、打开的文件以及文件创建掩码等信息。
(10)内存信息:
记录进程的代码映像和堆栈的地址、长度等信息。
(11)进程现场信息:
保存进程放弃CPU时所有CPU寄存器及堆栈的当前值。
4.查看进程的信息
ps命令
【功能】可查看记录在进程PCB中的几乎所有信息。
【格式】ps[选项]
【选项】
-e显示所有进程。
-f以全格式显示。
-r只显示正在运行的进程。
-o以用户定义的格式显示。
a显示所有终端上的所有进程。
u以面向用户的格式显示。
x显示所有不控制终端的进程。
【说明】
(1)默认只显示在本终端上运行的进程,除非指定了-e、a、x等选项。
(2)没有指定显示格式时,采用以下缺省格式,分4列显示:
PIDTTYTIMECMD
其余见教材page81
5.Linux进程的组织
Linux系统采用了多种方式来组织PCB,主要有以下几种。
1)进程链表
系统将所有的PCB链成一个双向循环链表,进程通过PCB中的list_head字段链入进程链表。
遍历该链表即可顺序地找到每个进程。
在许多情况下,内核需要根据进程的PID查找进程。
顺序扫描链表并逐个检查PCB中的PID是相当低效的。
为了加速查找,内核还设置了几个进程散列表,将PID直接映射到PCB。
2)进程树链表
Linux系统中,进程之间存在着父子关系。
除了init进程外,每个进程都有一个父进程,即创建了此进程的进程。
系统中的所有进程形成了一棵进程树,每个进程都是树中的一个节点,树的根是init进程,它是所有进程的祖先进程。
在PCB中设置有父进程指针parent、子进程指针children和兄弟进程指针sibling,它们构造出了进程树的结构。
进程通过这些指针可以直接找到它的家族成员。
3)可执行队列
为了方便进程的调度,系统把所有处于可执行状态的PCB组织成一个可执行队列,处于可执行状态的进程通过PCB中的run_list字段链入队列。
可执行队列中设置了一个curr指针,它指向队列中正在使用CPU的进程,用来区别就绪态和运行态的进程。
在进程切换时,进程调度程序从可执行队列中选择一个让其运行,并将curr指针指向它。
4)等待队列
进程因不同的原因而睡眠,系统将睡眠的进程分类管理,每类对应一个特定的事件,用一个等待队列链接。
等待队列是一个双向循环链表,链表的节点中包含了指向进程PCB的指针。
当某一事件发生时,内核会唤醒相应的等待队列中满足等待条件的进程,将唤醒的进程从队列中删除,加入到可执行队列中。
4.2进程的运行模式
进程的运行紧密依赖于操作系统的内核
4.2.1操作系统内核
内核(kernel)是操作系统的核心,它负责最基本的资源管理和控制工作,为进程提供良好的运行环境。
图4-5是Linux系统的层次体系结构。
系统分为3层:
最底层是系统硬件;硬件层之上是核心层,它是运行程序和管理基本硬件的核心程序;用户层由系统的核外程序和用户程序组成,它们都是以用户进程的方式运行在核心之上。
Linux系统的内核主要由以下成分构成:
(1)进程控制子系统,负责支持、管理和控制进程的运行,包括以下模块:
●进程调度模块,负责调度进程的运行。
●进程通信模块,实现进程间的本地通信。
●内存管理模块,管理进程的地址空间。
(2)文件子系统,为进程提供I/O环境,包括以下模块和成分:
●文件系统模块,管理文件和设备。
●网络接口模块,实现进程间的网络通信。
●设备驱动程序,驱动和控制设备的运行。
(1)系统调用接口,提供进程与内核的接口,进程通过此接口调用内核的功能。
(2)硬件控制接口,是内核与硬件的接口,负责控制硬件并响应和处理中断事件。
4.2.2中断与系统调用
由图可以看出,内核与外界的接口是来自用户层的系统调用和来自硬件层的中断,而系统调用本身也是一种特殊的中断。
因此可以说内核是中断驱动的,它的主要作用就是提供系统调用和中断的处理。
因此,了解内核的运行机制需要先了解中断和系统调用的概念。
1.中断
1)中断概念:
在中断方式下,CPU启动设备操作后,它不是空闲等待,而是继续执行程序。
当设备完成I/O操作后,向CPU发出一种特定的中断信号,打断CPU的运行。
CPU响应中断后暂停正在执行的程序,转去执行专门的中断处理程序,然后再返回原来的程序继续执行。
这个过程就是中断。
2)中断的概念是因实现CPU与设备并行操作而引入的。
然而,这个概念后来被大大地扩大了。
现在,系统中所有异步发生的事件都是通过中断机制来处理的,包括I/O设备中断、系统时钟中断、硬件故障中断、软件异常中断等。
这些中断分为硬件中断和软件中断(也称为异常)两大类。
每个中断都对应一个中断处理程序。
中断发生后,CPU通过中断处理入口转入相应的处理程序来处理中断事件。
2.系统调用
1)系统调用是系统内核提供的一组特殊的函数,用户进程通过系统调用来访问系统资源。
2)系统调用是内核中的程序代码,它们具有访问系统资源的特权。
当用户进程需要执行涉及系统资源的操作时,需要通过系统调用,让内核来完成。
3)系统调用是借助中断机制实现的,它是软中断的一种,称为“系统调用”中断。
当进程执行到一个系统调用时,就会产生一个系统调用中断。
CPU将响应此中断,转入系统调用入口程序,然后调用内核中相应的系统调用处理函数,执行该系统调用对应的功能。
4.2.3进程的运行模式
1. CPU的执行模式
CPU的基本功能就是执行指令。
通常,CPU指令集中的指令可以划分为两类:
特权指令和非特权指令。
1)特权指令是指具有特殊权限的指令,可以访问系统中所有寄存器和内存单元,修改系统的关键设置。
比如清理内存、设置时钟、执行I/O操作等都是由特权指令完成的。
2)非特权指令是那些用于一般性的运算和处理的指令。
这些指令只能访问用户程序自己的内存地址空间。
普通的应用程序只能使用那些没有危险的非特权指令
3)特权指令的权限高,如果使用不当则可能会破坏系统或其他用户的数据,甚至导致系统崩溃。
为了安全起见,这类指令只允许操作系统的内核程序使用。
普通的应用程序只能使用那些没有危险的非特权指令。
实现这种限制的方法是在CPU中设置一个代表运行模式的状态字,修改这个状态字就可以切换CPU的运行模式。
4)Linux系统只用到了其中两个,即称为核心态的最高特权级模式(ring0)和称为用户态的最低特权级模式(ring3)。
5)核心态下,CPU能不受限制地执行所有指令,从而表现出最高的特权。
6)在用户态下,CPU只能执行一般指令,不能执行特权指令,因而也就没有特权。
7)内核的程序运行在核心态下,而用户程序则只能运行在用户态下。
从用户态转换为核心态的唯一途径是中断(包括系统调用)。
一旦CPU响应了中断,则将CPU的状态切换到核心态,待中断处理结束返回时,再将CPU状态切回到用户态。
2.进程的运行模式
进程在其运行期间常常被中断或系统调用打断,因此CPU也经常地在用户态与核心态之间切换。
在进行通常的计算和处理时,进程运行在用户态;执行系统调用或中断处理程序时进入核心态,执行内核代码。
调用返回后,回到用户态继续运行。
图4-6描述了用户进程的运行模式切换。
第4.3节进程控制
1)进程控制是指对进程的生命周期进行有效的管理,实现进程的创建、撤销以及进程各状态之间的转换等控制功能。
2)进程控制的目标是使多个进程能够平稳高效地并发执行,充分共享系统资源。
4.3.1进程控制的功能
1)进程控制的功能是控制进程在整个生命周期中各种状态之间的转换
2)不包括就绪态与运行态之间的转换,它们是由进程调度来实现的
3)内核提供了几个原子性的操作函数,称为原语(primitive)。
A原语与普通函数的区别是它的各个指令的执行是不可分割的,要么全部完成,要么一个也不做,因而可以看做是一条广义的指令。
B用于进程控制的原语主要有创建、终止、阻塞和唤醒等。
(1)创建进程
创建原语的主要任务是根据创建者提供的有关参数(包括进程名、进程优先级、进程代码起始地址、资源清单等信息),建立进程的PCB。
具体的操作过程是:
先申请一个空闲的PCB结构,调用资源分配程序为它分配所需的资源,将有关信息填入PCB,状态置为就绪态,然后把它插入就绪(可执行)队列中。
(2)撤销进程
撤销原语用于在一个进程运行终止时,撤销这个进程并释放进程占用的资源。
撤销的操作过程是:
找到要被撤销的进程的PCB,将它从所在队列中摘出,释放进程所占用的资源,最后销去进程的PCB。
(3)阻塞进程
阻塞原语用于完成从运行态到等待态的转换工作。
当正在运行的进程需要等待某一事件而无法执行下去时,它就调用阻塞原语把自己转入等待状态。
阻塞原语具体的操作过程是:
首先中断CPU的执行,把CPU的当前状态保存在PCB的现场信息中;然后把被阻塞的进程置为等待状态,插入到相应的等待队列中;最后调用进程调度程序,从就绪(可执行)队列中选择一个进程投入运行。
(4)唤醒进程
唤醒原语用于完成等待态到就绪态的转换工作。
当处于等待状态的进程所等待的事件出现时,内核会调用唤醒原语唤醒被阻塞的进程。
操作过程是:
在等待队列中找到该进程,置进程的当前状态为就绪态,然后将它从等待队列中撤出并插入到就绪(可执行)队列中。
4.3.2Linux系统的进程控制
在Linux系统中,进程控制的功能是由内核的进程控制子系统实现的,并以系统调用的形式提供给用户进程或其他系统进程使用。
1.进程的创建与映像更换
系统启动时执行初始化程序,启动进程号为1的init进程运行。
系统中所有的其他进程都是由init进程衍生而来的。
除init进程外,每个进程都是由另一个进程创建的。
新创建的进程称为子进程,创建子进程的进程称为父进程。
Unix/Linux系统建立新进程的方式与众不同。
它不是一步构造出新的进程,而是采用先复制再变身的两个步骤,即先按照父进程创建一个子进程,然后再更换进程映像开始执行。
1)创建进程
(1)创建一个进程的系统调用是fork()。
(2)创建进程采用的方法是克隆,即用父进程复制一个子进程。
做法是:
先获得一个空闲的PCB,为子进程分配一个PID,然后将父进程的PCB中的代码及资源复制给子进程的PCB,状态置为可执行态。
建好PCB后将其链接入进程链表和可执行队列中。
此后,子进程与父进程并发执行。
父子进程执行的是同一个代码,使用的是同样的资源。
(3)它与父进程的区别仅仅在于PID(进程号)、PPID(父进程号)和与子进程运行相关的属性(如状态、累计运行时间等),而这些是不能从父进程那里继承来的。
(4)fork()系统调用
【功能】创建一个新的子进程。
【调用格式】intfork();
【返回值】
0向子进程返回的返回值,总为0
>0向父进程返回的返回值,它是子进程的PID。
-1创建失败。
【说明】若fork()调用成功,则它向父进程返回子进程的PID,并向新建的子进程返回0。
图4-7描述了fork()系统调用的执行结果。
A从该调用点之后分裂成了两个进程:
一个是父进程,从fork()后的代码处继续运行;另一个是新创建的子进程,从fork()后的代码处开始运行。
B与一般函数不同,fork()是“一次调用,两次返回”,父进程得到的返回值是一个大于0的数,它是子进程的PID;子进程得到的返回值为0。
C通常的做法是:
在fork()调用后,通过判断fork()的返回值,分别为父进程和子进程设计不同的执行分支。
例4.2一个简单的fork_test程序:
#include
main()
{intrid;
rid=fork();
if(rid<0){printf(“forkerror!
”);return;}
if(rid>0)//父进程分支
printf(“Iamparent,myridis%d,myPIDis%d\n”,rid,getpid());
else//子进程分支
printf(“Iamchild,myridis%d,myPIDis%d\n”,rid,getpid());
}
由于两进程是并发的,它们输出信息的先后次序不确定,有可能父先子后,也可能相反。
2)更换进程映像
(1)通常用户需要的是创建一个新的进程,它执行的是一个不同的程序。
Linux系统的做法是,先用fork()克隆一个子进程,然后在子进程中调用exec(),使其脱胎换骨,变换为一个全新的进程。
(2)exec()系统调用的功能是根据参数指定的文件名找到程序文件,把它装入内存,覆盖原来进程的映像,从而形成一个不同于父进程的全新的子进程。
除了进程映像被更换外,新子进程的PID及其他PCB属性均保持不变,实际上是一个新的进程“借壳”原来的子进程开始运行。
(3)exec()系统调用
【功能】改变进程的映像,使其执行另外的程序。
【调用格式】exec()是一系列系统调用,共有6种调用格式,其中execve()是真正的系统调用,其余是对其包装后的C库函数。
intexecve(char*path,char*argv[],char*envp[]);
intexecl(char*path,char*arg0,char*arg1,...char*argn,0);
intexecle(char*path,char*arg0,char*arg1,...char*argn,0,char*exvp[]);
…
【参数说明】path为要执行的文件的路径名,argv[]为运行参数数组,envp[]为运行环境数组。
arg0为程序的名称,arg1~argn为程序的运行参数,0表示参数结束。
例如:
execl(“/bin/echo”,“echo”,“hello!
”,0);
execle(“/bin/ls”,“ls”,“-l”,“/bin”,0,NULL);
前者表示更换进程映像为/bin/echo文件,执行的命令行是“echohello!
”。
后者表示更换进程映像为/bin/ls文件,执行的命令行是“ls-l/bin”。
【返回值】调用成功后,不返回,调用失败后,返回
-1。
与一般的函数不同,exec()是“一次调用,零次返回”,因为调用成功后,进程的映像已经被替换,无处可以返回了。
图4-9描述了用exec()系统调用更换进程映像的流程。
子进程开始运行后,立即调用exec(),变身成功后即开始执行新的程序了。
例4.3一个简单的fork-exec_test程序:
#include
main()
{intrid;
rid=fork();
if(rid>0)printf(“Iamparent\n”);
else{printf(“Iamchild,I’llchangetoecho!
\n”);
execl(“/bin/echo”,“echo”,“hello!
”,0);//更换为echo
}
}
2.进程的终止与等待
1)进程的终止与退出状态
导致一个进程终止运行的方式有两种:
一是程序中使用退出语句主动终止运行,我们称其为正常终止;另一种是被某个信号杀死(例如,在进程运行时按Ctrl+c键终止其运行),称为非正常终止。
关于信号的介绍见0节。
用C语言编程时,可以通过以下4种方式主动退出:
(1)调用exit(status)函数来结束程序;
(2)在main()函数中用returnstatus语句结束;
(3)在main()函数中用return语句结束;
(4) main()函数结束。
2)终止进程
进程无论以哪种方式结束,都会调用一个exit()系统调用,通过这个系统调用终止自己的运行,并及时通知父进程回收本进程。
exit()系统调用完成以下操作:
释放进程除PCB外的几乎所有资源;向PCB写入进程退出状态和一些统计信息;置进程状态为“僵死态”;向父进程发送“子进程终止(SIGCHLD)”信号;调用进程调度程序切换CPU的运行进程。
至此,子进程已变为“僵尸进程”,它不再具备任何执行条件,只是PCB还在。
保留PCB的目的是为了保存有关该进程运行情况的重要的信息,比如这个进程的退出
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第四 中央处理器 教案