收藏 分享(赏)

第六章 进程控制.ppt

上传人:scg750829 文档编号:9174956 上传时间:2019-07-26 格式:PPT 页数:120 大小:877.50KB
下载 相关 举报
第六章 进程控制.ppt_第1页
第1页 / 共120页
第六章 进程控制.ppt_第2页
第2页 / 共120页
第六章 进程控制.ppt_第3页
第3页 / 共120页
第六章 进程控制.ppt_第4页
第4页 / 共120页
第六章 进程控制.ppt_第5页
第5页 / 共120页
点击查看更多>>
资源描述

1、第六章 进程控制,大纲,1 进程基本概念 2 UNIX系统中的进程 3 UNIX系统进程调度和管理 4 UNIX系统进程存储管理 5 UNIX进程的建立与运行 6 UNIX进程的控制,1 进程的基本概念,设计操作系统的主要目标是充分利用硬件资源使其发挥最大的效能。处理机(CPU)资源,又是其中最重要的一项,让它尽可能处于工作状态,是操作系统管理功能的关键。调度针对的主要是处理机资源的分配问题,因而处理机管理的核心是调度。 处理机调度的主要指标有:周转时间、吞吐量、响应时间和设备利用率等。根据不同的使用场合、不同的系统需求,选取合适的调度算法,采用不同的管理侧重点,使系统达到预期的性能指标是调度

2、管理的主要任务。,处理机调度也是分层次的,按照调度发生频率依次是:作业调度、交换调度、进程调度和线程调度。 作业调度,是针对用户提交的作业,在已经输入的作业中,按照某种策略,选取合适的作业投入运行。 交换调度,又称中级调度。针对系统中已经开始运行的进程,把内存中暂时不会执行的内容交换到外部存储器的特定区域中,而把外存中处于就绪状态的进程交换到内存中,准备投入执行。 进程调度,控制进程在执行、就绪、等待等各种状态之间转换经历的过程。特别是从就绪到执行的转换,系统从处于就绪状态的所有进程中选择合适的一个,分配处理机资源,投入执行。,1 进程的基本概念,线程调度,系统内核针对线程的调度情况,选中就绪

3、线程并占有处理机,转入执行状态。,外存,内存,提交 状态,收容 状态,就绪,阻塞,就绪,执行,阻塞,完成 状态,交换调度,作业调度,进程调度,线程调度,输入管理系统,1 进程的基本概念,UNIX系统是分时多任务、多道程序环境系统。它采用时间片轮转转方式为系统中的多个用户的多道程序提供服务。为了跟踪计算机并行活动的状态及并发程序对资源的共享使用,提出了进程的概念。,1 进程的基本概念,1进程与程序,(a)程序:程序代码,静态进程:可以看作某种特定任务的程序在一个数据集合上的一次具体的活动,动态。,(b)进程与程序相比具有动态性、独立性、并发性等特点。,1 进程的基本概念,2进程的描述,进程的结构

4、进程描述信息 进程实体,PCB:包括进程的描述信息、控制信息及进程使用资源信息、处理器现场保护结构等,PCB包含的内容是进程动态特征的集中反映。OS通过PCB感知一个进程的存在。 程序段:进程需要完成功能的程序代码。 数据结构集:进程的程序执行时操作的对象。,1 进程的基本概念,3进程的状态程序 静态进程 动态,具有生命周期,两状态进程模式:,两状态进程模式中包含的进程状态转换过程: 进程开始;调度运行;暂停运行;进程结束,1 进程的基本概念,五状态进程模式:,五状态进程模式中包含的进程状态转换过程: 创建新进程;进程提交;调度运行;释放;超时;事件等待;事件发生,1 进程的基本概念,4进程控

5、制主要实现进程状态的转换和并发进程的管理1)原语 不可分解,不间断,不可并发执行的程序段2)临界区 指共享某个资源时,不允许多个并发的程序交叉执行的一段代码, 程序需要互不干涉。并发产生的原因:进程随机发生3)进程互斥 4)信号量 描述共享资源使用情况的数据结构 5)进程同步有两种方式:互斥: 我在,你不能在 间接制约关系同步: 你不来,我不能走 直接制约关系,2 UNIX中的进程,1 UNIX创建进程的过程,2 UNIX中的进程,2UNIX中进程的描述运行中的每个进程都有一个独立的运行环境,这个环境是进程生存的基础,即进程上下文 。,Linux系统中同时在内存中安排多个进程,这些进程相互之间

6、竞争处理机的使用权。系统的低级调度,即进程级调度就是要按照一定的策略,从所有处于就绪状态的进程中选择最应该执行的进程,把CPU分配给它,开始执行。Linux系统的内核级线程也按照进程来对待,使用进程调度统一处理进程和内核级线程。,3 UNIX进程调度和管理,Linux系统的所有进程共同构成一个完整的进程树,如上图所示。从init进程开始, init进程是所有其他进程的祖先。init产生终端管理进程mingetty,mingetty产生login,login产生用户的shell进程,然后shell产生其他用户进程,因此,其他所有进程都是由init或者它的子孙创建而来。同样,在进程结束之后,父进程

7、也要负责该进程的最后回收工作,如果某一个进程创建了子进程之后,由于某种原因先于子进程终止,由它创建的子进程成为孤儿进程,孤儿进程的祖父进程就要负责回收工作,依此类推。最后,在系统要关机之前,init进程还要负责结束所有的进程,卸载所有文件系统并终止处理器的指令执行。,3 UNIX进程调度和管理为了管理进程,Linux系统采用多种方式来组织处于各种状态的进程。系统中每创建一个新的进程,就给它分配一个进程控制块(PCB), PCB是系统感知、控制进程的静态实体。系统访问PCB的频率非常高,因此所有进程的PCB都直接存放在物理内存中。Linux系统中使用一个称为task的数组来保存所有PCB的指针,

8、Linux通过task数组来管理系统中所有的进程。每一个进程都有一个惟一标识自己的进程号PID,进程号和进程在task数组中的位置(数组元素的下标)之间是不同的。,同时,系统中所有的进程还构成一个双向循环队列,整个队列通过进程控制块中的两个指针next-task和prev-task来维护。某个进程在整个进程树中的位置,也通过PCB中指针描述。为了方便进程的调度,系统把所有可运行的进程组织成一个可运行队列,系统通过当前(current)指针来区别就绪状态和执行状态,每一个CPU都有一个当前指针,指向正在使用该CPU的进程。可运行队列也是一个双向循环队列,队列中指向前后接点的指针同样存放在PCB中

9、,它们是next-run和prev-run。系统的调度函数根据一定的规则,查找整个可运行队列,在其中寻找最值得执行的进程,给它(或它们)分配CPU,投入执行。,Linux系统内部把所有进程分为三类,空闲线程、内核线程和用户进程。空闲线程是系统中一个特殊的具有标志作用的进程,它是task数组的0号元素task0,它的进程号也是0,在源代码中记作init-task,只有当整个系统中没有进程可以运行时,空闲线程才会执行,它始终位于系统可运行队列中,也是该队列的头结点,同时它也是所有进程组成的队列的头结点。内核线程也是比较特殊的进程,它处于核心态,没有虚拟地址空间,拥有很高的优先权,一般用来完成系统管

10、理任务,内核交换进程kswapd就是其中之一。用户进程包括所有其他进程和线程,可以在用户态和核心态两种模式下运行。,注意,空闲进程init-task和系统中的1号进程init在表达上很相象,但二者完全不同,空闲进程是进程组织、调度过程中的关键性标志,它本身不完成任何任务,它不会退出也不会进入等待状态,而init进程是系统启动后第一个有用的进程,它负责启动系统中相关进程,在系统要关机之前,init进程还要负责结束所有的进程,它是系统中整个进程树的祖先。,调度函数是Linux系统中执行最为频繁的一个,它的主要目标就是选择合适的进程占有CPU,实现程序的多道执行,充分提高CPU的利用率。调度函数通过

11、对每个进程PCB中相关信息查询,按照一定的算法,在可运行队列选择进程。如果选中的进程并不是当前占有处理机的进程,调度函数还负责保存当前进程的执行现场(进程上下文),然后恢复选中进程的进程上下文使之顺利执行。Linux系统中没有设置专门的调度进程,在需要调度的时候,调用一个特定的调度函数来完成调度功能。一般来讲,Linux系统中的进程调度发生的时机有下面几种。,(1) 用户利用系统提供的函数调用创建一个新的进程时,系统把它加到可运行队列中,返回该进程的进程号。这时,调度函数开始执行,这样的方案可以保证系统具有很好的响应特性。 (2) 当正在执行的进程申请某种暂时无法获得的资源或者为了与其他进程保

12、持同步,需要等待某个事件的发生,进程的PCB进入相应的等待事件队列中,进程转入等待状态; 当正在执行的进程完成了任务或者得到特定的信号而退出,转入僵死状态。这两种进程状态转换完成后,进程主动放弃CPU资源,调用调度函数,选择新的进程来使用CPU。这种情况下,及时的调度在一定程度上可以提高CPU资源的利用率。,(3) 对于分时系统,每个进程执行完一定的时间片之后,就必须交出CPU资源,这时,也要发生调度,这样的方案可以保证一定的公平性。 (4) 我们知道,Linux系统提供了两级保护,用户进程可以在用户态和核心态这两种处于不同保护模式的情况下运行,具有不同的特权级别,可以访问的地址空间不同。用户

13、进程可以在这两种模式之间进行切换,用户态通过中断或函数调用就可以转入核心态,其中中断是应进程外部发来的信息的要求而转入核心态,函数调用则是进程内部要求转入核心态。而从核心态切换到用户态,则需要一定的硬件支持。当进程从核心态返回到用户态时,将会调用调度函数,发生调度。,从本质上来看,这些情况可以归结为两类时机:一是进程本身自动放弃处理机发生调度,这包括进程转换到等待和僵死状态,这类调度是用户进程可以预测的;二是由核心态转入用户态时发生调度,这类调度发生最为频繁。系统调用完成和内核处理完中断之后系统是由核心态转入用户态,时间片用完本身也是系统发送的时钟中断,本质上也是一种中断,而可运行队列加入新的

14、进程的工作只能由内核操作完成,无疑是发生于内核态。,3 UNIX进程调度和管理操作系统所采用的进程调度算法取决于系统最初的设计目标,它决定了系统对资源,特别是CPU资源的分配策略,直接决定着系统的特性。Linux系统采用相当简单但效率很高的调度算法,具有很好的响应特性,它提供了三种调度算法:POSIX操作系统标准规定的用于实时进程的先进先出算法(FIFO,First In First Out)和轮转算法(RR,Round Robin),用于普通进程的可抢占式动态优先级算法(Preemptive Scheduling)。,Linux先进先出调度算法按照实时进程进入可运行队列的先后顺序,依次把每一

15、个进程投入执行,只有前面的进程执行完成或者自动放弃CPU(比如进入等待状态),下一个进程才可以执行。这样的算法实现简单,在一般意义下也还算公平合理,但是,如果一个执行很短的进程不小心排在一个执行时间很长的进程之后,那就可能要花费比执行时间长很多倍的时间来等待,显然是不可接受的。Linux系统的先进先出算法同时也考虑了进程的优先级,具有相同优先级的进程采用FIFO算法,如果有更高的优先级出现,调度函数就要选择具有高优先级的进程使用处理机,在新进程被加入到可运行队列之后出现的调度时机实际就可以解决这种问题。,Linux轮转算法的基本原理是给每一个进入可运行队列的实时进程分配固定大小的CPU处理时间

16、(称为时间片),按照它们在队列中的顺序依次开始执行,如果一个进程的时间片用完之后还没有完成要求的任务,它必须交出CPU的使用权并且重新排到可运行队列的尾部,等待下一次调度,原来排在它后面的进程投入执行。这样的算法,可以保证每个进程就绪之后的等待时间和占用CPU的时间成比例,更加公平。Linux系统使用的RR算法也考虑了进程的优先级,具有相同优先级的进程采用RR算法,而具有更高优先级的实时进程拥有首先使用CPU的权利。这样的方案,可以保证具有高优先级的紧迫型实时进程很快得到响应。,从上面的描述可以看到,Linux提供的实际是软件实时。Linux系统中,非实时进程的调度采用抢占式动态优先级算法。每

17、个进程拥有不变的静态优先级和可变的动态优先级,调度函数根据各进程的优先级来确定权值,拥有最大权值的进程被选中执行,如果多个进程具有相同权值,则选取排在可运行队列最前面的那一个。每一个进程都分配一定的时间片,时间片使用完之后,系统转入调度函数,等所有非实时进程的时间片都使用完之后,再按照各自的优先级给每个进程重新分配时间片。,时间片是系统中比较关键的一个参数,它的大小直接影响系统的性能。I386系统采用段页式存储管理,进程的切换效率比较低,针对这种情况,Linux 时间片默认值为200ms,用户可以针对不同的进程设置时间片的值。事实上,Linux系统中并没有根据进程的调度策略分别管理进程,而是把

18、所有可运行进程都集中于同一个队列中,三种调度算法在实现过程中合为一种,使用同一段程序。,3 UNIX进程调度和管理Linux系统的调度过程简洁而高效。整个调度过程大概可以分为五个部分。首先检测中断,如果有中断运行时,调度过程到此为止,直接退出,如果没有中断运行,关中断,在调度的过程中将不再允许中断。其次处理系统的内核例程。然后对当前进程做相关处理:如果当前进程是时间片用完的进程按照轮转法调度,系统重新赋予时间片并把它移到队列的尾部;如果进程因为等待某个事件而转入等待状态引起调度,调度过程中发现事件已经发生,进程仍然转入就绪状态;如果进程处于其他非可运行态的话,就要从可运行队列中删除。这些都是为

19、开始调度而进行的准备工作。,接着调度函数遍历整个可运行队列,从中找到最值得运行的进程,该进程的权值(goodness)最大。如果该进程不是当前进程,系统需要进行进程上下文切换,如果正好就是当前进程,这一部分就可以跳过去。最后打开中断,选中的进程开始执行。整个调度过程的核心就是如何计算一个进程的权值。在Linux系统中,决定进程权值的相关参数有四个,它们都记录在进程控制块中: (1) policy,策略,一个给定进程采用的调度算法称为该进程的调度策略。进程的调度策略是从父进程那里继承来的,但是也可以通过特定系统调用来改变。,(2) priority,优先级,确切地讲是静态优先级。记载了进程最多可

20、以拥有的时间片,从父进程那里继承过来,只能由用户通过系统调用来修改。 (3) counter,计数器,它实际上是进程的动态优先级。它表示进程在当前时间片中剩余的时间量。它的初值等于静态优先级,在进程执行期间,随时间不断减少,当它小于或等于0时,表明进程的时间片用完,重新设置为0,并引起调度。 (4) rt-priority,实时优先级。实时进程的优先级,标志实时进程优先权的高低。取值范围为099,取0时表示不是实时进程。,系统在进行调度时,首先确定该进程的调度策略,依据就是policy的值,然后根据不同的策略,选用适当的算法具体计算相应的权值,权值是衡量一个进程是否执行的惟一标准。衡量实时进程

21、执行的依据就是实时优先级。具体的计算公式为: goodness=1000+rt-priority (6.1)对于采用实时FIFO策略的进程,具有高实时优先级的进程将一直执行,直到进入僵死状态、进入等待状态或者是被具有更高实时优先级的进程夺去处理机。采用实时RR策略的进程,时间片用完之后,将被放到可运行队列的尾部,等待下一次调度,处理机由下一个具有相同实时优先级的进程使用。,普通进程的调度策略标记为SCHED-OTHER,采用抢占式动态优先级调度策略。选择执行的依据是进程的动态优先级。进程创建之初,动态优先级和静态优先级具有相同的值,随着进程的执行,动态优先级慢慢减小,如果一个普通进程时间片用完

22、的话,它的动态优先级就是0,而且要等到其他所有进程的动态优先级为0时才用静态优先级的值来初始化。这种情况下所有普通进程权值的计算公式都是: goodness=counter+priority (6.2)因此,在调度中,用完时间片的普通进程被选中的可能性很小,这就给其他进程,特别是新建进程使用处理机的机会。,如果进入调度后,当前普通进程的时间片没有用完,而且仍然位于可运行队列中时,当前进程的权值采用公式(6.3)计算,除了当前进程之外的所有普通进程仍采用公式(6.2)计算权值。 goodness=counter+priority+1 (6.3)这样,适当增大当前进程的权值,以增加继续使用处理机的

23、可能,可以避免过分频繁的进程切换。新的普通进程进入可运行队列后,插入到队列尾部,将引起调度,在都使用相同静态优先级的情况下,新进程的权值很大,因此,如果没有实时进程和其他一直未执行过的就绪进程,新建进程投入执行的可能性相当大。可见,Linux系统所采用的这种调度算法优先保证交互性,系统的响应时间比较短。,实时进程和普通进程相比,总是具有更高的优先级。因此,如果可运行队列中同时存在实时进程和普通进程,实时进程总是可以先使用处理机。权值是Linux系统进程调度过程中选择进程的惟一标准,程序实现非常简单,参看kernel/sched.c。,4 Unix系统进程存储管理,存储管理的主要功能: (1)存

24、储空间的分配,回收; (2)地址变换; (3)存储共享和保护; (4)存储器扩充 (5)提高主存的利用率,计算机的存储结构图:,4.1 进程存储技术,程序以进程的方式存放于内存中,CPU在内存中实现进程之间的切换调度。采用一些策略和算法来分配存储空间,使进程在内存和磁盘之间来回切换。此过程为进程的存储管理过程。,1连续分配存储技术操作系统为运行的进程分配一个连续的内存空间(a) 单一连续分配存储方式:,4.1 进程存储技术,1连续分配存储技术操作系统为运行的进程分配一个连续的内存空间(b)分区式连续存储方式:,4.1 进程存储技术,(1)覆盖目的: 在较小的可用内存中运行较大的程序 原理: 一

25、个程序的几个代码段或数据段按照使用的先后顺序以覆盖方式占用共享内存区域。原则: 将程序中必要的数据放在常驻内存中。 将不经常用的放在交换区。将不存在调用关系的模块可以采用覆盖方式共享内存分区。,(2)交换:在多个程序并发执行的时候,将暂时不执行的代码放入交换区,从而可以用更大的内存空间装入新的进程。,2覆盖和交换技术,现代操作系统中普遍采用基于虚拟存储器的概念来统一管理内存和外存,实现逻辑上的大容量存储空间。从内存中换出的页面保存在外存的交换空间中,Linux系统提供两种不同类型的外存保存方式。一种是利用整个块设备,比如磁盘的一个分区,这样的分区具有特殊的格式,通常称为交换区或交换设备。另一种

26、是利用文件系统中特殊的文件,这种文件具有固定的长度,称为交换文件。,4.1 进程存储技术 交换空间,Linux系统可以同时管理多个交换空间,最大个数由参数MAX-SWAPFILES指定(默认值是8),在文件include/linux/swap.h中定义。交换空间按照优先级排序,当需要分配一个交换页面时,Linux首先使用仍然拥有空间、拥有最高优先级的交换空间,交换区和交换文件都可以用来存储内存中换出的页,达到扩充内存的目的。使用交换区的交换存取过程中,系统直接针对磁盘进行。交换文件是文件系统中的特殊文件,在文件系统建立之后创建。在实际使用过程中,通常以交换区为主,以交换文件为辅。首先设置能够满

27、足日常工作需要的交换区,当需要更多交换空间的时候,临时增加几个交换文件,这样,不再需要时可以方便地撤消交换文件。,4.1 进程存储技术 Linux系统中进程虚拟存储空间管理的基本单位是虚拟存储段(Vitual Memory Area, VMA),用vm-area-struct 结构来描述。一个VMA段是某个进程的一段连续的虚拟空间,这段存储空间的所有单元(页)拥有相同的特征,这些特征可以包括访问权限、保护情况可加锁情况等等,同时,还定义了一组建立在这个数据结构基础上的对内存的操作方法,这些操作方法具体实现进程对虚拟存储段的操作,见图4.2。进程的虚拟内存实际是由一组指向vm-area-stru

28、ct 结构的指针的链表来具体实现的,链表的头接点记录在该进程所指向的mm-struct结构中。,图4.2 vm-area-struct 数据结构示意图,当可执行程序映射到进程的虚拟地址空间时,系统建立一系列 vm-area-struct结构来描述虚拟内存区域的起始点和终止点,每一个结构代表可执行程序的一个部分,可能是可执行代码,也可能是初始化的变量或未初始化的数据。随着整个vm-area-struct结构组成的链表的生成,这个结构所描述的虚拟内存区域上的标准操作函数也由Linux初始化。进程映射到虚拟空间中并开始执行后,因为只有很少一部分被装入了物理内存,因此不久进程就会存取尚未装入物理内存的

29、虚拟内存页,这时,处理器向Linux报告一个页故障及其对应的故障原因,根据实际情况,系统必须把进程执行所需要的内容装入到物理内存,换入工作开始了。,4.2 虚拟存储技术,1局部性原理程序执行过程中,在较短的时期内,所执行的指令地址以及操作数地址分别局限在一个区域内。时间局限性: 当前指令执行与下条指令执行,数据的当前访问和下次访问集中在一个时间段中。空间局部性: 当前访问指令和临近访问的指令,当前访问的数据和临近访问的数据集中在一个较小区域内。原因:大部分程序在空间上顺序执行,在时间上循环执行,4.2 虚拟存储技术,2虚存的原理只需将当前需要执行的部分页和部分段读入到内存中就可让程序开始执行。

30、利用缺页和缺段请求,动态实现存储管理。,3特点: 存储空间变大 内存外存, 支持程序的并发执行,采用部分交换。,4虚拟存储器的种类1)页式虚存2)段式虚存3)段页式虚存,4.3 UNIX进程存储管理,1交换策略早期 内存和交换区之间传送整个进程费时,影响效率现代 部分交换关键信息,PCB不参与交换,常驻内存。0号进程负责调度和交换工作,无限循环的执行。数据结构 映射图来管理交换设备的空间资源,包含可分配的资源地址及该地址可用的资源单位。,UNIX系统采用交换和请求调页两种策略完成存储管理,4.3 UNIX进程存储管理,2请求调页策略内存分页 外存分页进程运行时系统只在内存中保留当前活动进程的某

31、些页面,而不放入整个进程页面缺页中断 虚存技术不受空间限制为了提高运行效率,核心进程提供了一个工作区,存放内存中最近被访问过的页面集合。,3UNIX系统中进程存储管理结构Proc User PCB放内存中 放外存中,4.3 UNIX进程存储管理,请求表:系统有一个请求表,可以放到PCB描述中,存储页面表: 系统有一张,用于描述内存各个页面的分配情况,动态页式管理:只需要将执行部分调入(缺页中断则调入),动态管理程序各部分在内存中的调入调出。,换入进程内存页的换入是从缺页故障开始的,这种页故障出现的原因可能有两种,第一种情况是程序出现内存访问错误;另一种情况就是正常的缺页中断,虚拟地址有效,但其

32、所对应的页当前不在物理内存中,这时,操作系统必须从磁盘映像或交换空间中将所需的页装入物理内存。进程运行过程中遇到缺页中断后,系统保存当前进程的现场,当前进程进入等待状态。Linux系统转入缺页中断处理程序,根据处理器提供的缺页地址信息(在I386系统中是控制寄存器CR2),系统必须迅速地找到用来表示出现缺页的虚拟存储区所对应的vm-area-struct结构。,为了实现快速查找出现页故障虚拟内存相应的vm-area-struct结构的位置目标,Linux内核把所有vm-area-struct结构组成一个AVL树(自平衡二叉查找树 ,在AVL树中任何节点的两个子树的高度最大差别为一 )。如果搜索

33、不到缺页所对应的内存区域,则说明进程访问了非法存储区,该虚拟地址是无效的,系统向进程发送SIGSEGV信号。接着,系统进行缺页访问模式合法性检测。因为进程也有可能在虚拟地址上进行的操作非法而产生页故障。这时操作系统会同样发送内存错误信号SIGSEGV给该进程。有关页的访问控制信息包含在页表项中。,这两项检测通过之后,就表明该虚拟地址有效。对有效的虚拟地址,必须区分页所在的位置。如果页表项是无效但非空,则说明该页处于交换空间中,操作系统要从交换空间装入页,否则,页面就位于磁盘的可执行映像中。默认情况下,Linux会分配一个新的物理页面并建立一个有效的页表项,更新页表项的相关属性信息,把所需要的页

34、面装入内存。这时,所需的页装入了物理内存,页表项也同时被更新,然后进程就可以继续执行了。这就是请求页式管理的请求调页过程。处理缺页故障过程中操作系统唤醒另外的进程占有处理机资源,当前进程转入等待状态。换入结束后,进程转入就绪状态,参与处理机资源的竞争。,换出系统为了保证有足够的空闲物理内存,必须及时把内存中暂时不会用到的物理页面淘汰掉,或者说置换出去,可能是置换到交换空间,也可能直接扔掉,这取决于页面本身的访问情况。Linux系统提供内核交换进程kswapd来实现页面淘汰功能。kswapd进程号为5,属于一种特殊的进程,Linux中称为内核线程,内核线程不是通常意义的线程,它是具有高优先级的实

35、时进程,不共享其他进程的内容,本身没有虚拟存储空间,运行于内核态,直接访问物理空间,这种特性决定了它可以快速地使用内存,提高整个内存管理的效率。属于这个类型的进程还有init和bdflush等等。,内核线程kswapd主要是保证系统中总是有足够的空闲页面,保持整个存储管理子系统高效地运行。这个线程周期性地运行,可以保证系统总能及时释放足够多的内存页面。交换内核线程kswapd周期性地被唤醒,首先检测现有的空闲内存页面数据,Linux系统使用固定的值作为空闲页面的警戒值。交换内核线程kswapd是高优先级实时进程,依次通过三种途径缩减已使用的内存页面: 一是缩减page cache和buffer

36、 cache;二是换出SYSTEM 共享内存占用的页面;三是换出或者丢弃其他进程占用的页面。释放一部分页面之后,系统再次拥有足够多的空闲页面,交换内核线程转入等待状态。,缩减page cache和buffer cache是Linux操作系统首选的释放页面途径。page cache是系统为了提高磁盘文件访问速度而设置的,磁盘文件中正在访问的一部分以页为单位映射到内存中。buffer cache是系统块设备使用的缓冲区,其目标是提高块设备的访问速度。在释放物理内存时,淘汰cache页面是最简便的办法。如果缩减page cache和buffer cache没有得到足够多的空闲页面,就采取第二步措施,

37、换出SYSTEM 共享内存。共享页面由多个进程访问,只能换出到交换空间中,而且共享页面同时涉及到多个进程,因此在换出过程中必须依次对每一个进程的页表进行修改,这也需要多次访问内存,增加了工作量。,上述两种措施仍然没有得到足够的空闲页面时,系统就要对所有进程进行扫描,寻找适合换出的候选进程。好的候选进程应该有一个或多个可以丢弃或换出的页面,系统选择其中部分页面丢弃或换出。Linux系统采用记龄(aging)置换算法。Linux系统根据访问次数来决定是否适合换出,优先换出那些很长时间没有访问的页面。与前两种途径相比,换出或者丢弃其他进程占用的页面的效率最低。总的来看,请求页式存储管理方法在进程建立

38、时只分配少量内存,通过页面的交换来保证进程运行的时候能够得到需要的页面,可以同时在内存中安排多个进程。但是,内存利用率的提高是以牺牲系统时间开销为代价换来的。,5. 进程的建立与运行,进程标识 每个进程都有一个非负整型的唯一进程ID。,62,一些特殊进程: 进程ID 0 调度进程,常常被称为交换进程; 进程ID 1 通常是init进程,在启动时由内核调用;,63,5.进程的建立与运行,获取进程信息,64,#include #include pid_t getpid(void); 返回:调用进程的进程ID pid_t getppid(void); 返回:调用进程的父进程ID uid_t getu

39、id(void); 返回:调用进程的实际用户ID uid_t geteuid(void); 返回:调用进程的有效用户ID gid_t getgid(void); 返回:调用进程的实际组ID gid_t getegid(void); 返回:调用进程的有效组ID,没有出错返回,real user ID:实际用户ID,指的是进程执行者是谁; effective user ID:有效用户ID,指进程执行时对文件的访问权限 ; saved set-user-ID:保存设置用户ID,作为effective user ID的副本, 在执行exec调用后能重新恢复原来的effectiv user ID 。 s

40、et-user-ID:设置用户ID,这是相对于文件来说的。设置了set-user-ID位的可执行程序,执行时,进程的effective user ID与saved set-uesr-ID都为程序文件所属用户的ID,这时real user ID与effective user ID就不一定相等了。这类程序称之为SUID程序。这类程序有特殊的用途,典型的例子:passwd程序,ping程序等。 passwd程序是要修改用户密码,此时是要修改/etc/passwd或修改/etc/shadow文件(有必要时),然而一般用户没有修改这两个文件的权限,passwd程序设置了set-user-ID位的,并且该

41、文件的所有者都是root,所以,一般用户执行时,也具有了root的权限.,5.进程的建立与运行,创建新进程,66,#include #include pid_t fork(void); 调用一次,返回两次:在子进程中返回0;在父进程中返回子进程的进程ID;出错则返回-1,5.进程的建立与运行,UNIX系统在实现fork()调用完成的主要工作: 1)为子进程在进程表中分配一个空闲的proc结构 2)赋给子进程一个唯一的进程标识符pid 3)复制一个父进程上下文的逻辑副本 4)增加与父进程相关联的文件表和索引节点表的引用次数 5)对父进程返回子进程的标识符为pid,对子进程返回标识符pid,5.

42、进程的建立与运行,parent,child,child,child,parent,fork,exec,exit,自动,wait,5. 进程的建立与运行,#include main() int pid;pid = fork();if ( pid 0 )printf(“fork failed!”); exit(1);if( pid = = 0)exec(“ls”, “-l”,0); elseprintf(“This is the parent process”); ,5.进程的建立与运行,创建新进程,70,为什么子进程中只需返回0,而无需返回父进程的进程ID?子进程中可以调用getppid()函数

43、来获得父进程的进程ID,为什么在父进程中要返回子进程的进程ID?一个父进程可能有多个子进程,所以在调用fork()函数创建新进程时就需要保存新创建的子进程的进程ID,5.进程的建立与运行,创建新进程子进程和父进程继续执行fork()之后的命令;子进程是父进程的复制品,子进程获得父进程的数据空间、堆、栈的复制品;现在很多的实现并不做一个父进程数据段和堆的完全copy,只对需要修改的数据段或堆进行copy;,71,72,#include “ourhdr.h“int glob = 6; /* external variable in initialized data */ char buf = “a

44、 write to stdoutn“;int main(void) int var; /* automatic variable on the stack */pid_t pid;var = 88;if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)err_sys(“write error“); /* we dont flush stdout */printf(“before forkn“); ,if (pid = fork() 0) err_sys(“fork error“); else if (pid = 0) /*

45、child */glob+; /* modify variables */var+; else sleep(2); /* parent */printf(“pid = %d, glob = %d, var = %dn“, getpid(), glob, var);exit(0); ,$ ./a.out a write to stdout before fork pid = 430, glob = 7, var = 89 childs variables were changed pid = 429, glob = 6, var = 88 parents copy was not changed

46、 $ ./a.out temp.out $ cat temp.out a write to stdout before fork pid = 432, glob = 7, var = 89 before fork pid = 431, glob = 6, var = 88,第五章我们讲过write函数是不带缓存的,直接调用系统核心函数执行输出。由于write先于fork命令调用,因此write只往标准输出写一次数据。而标准输入输出函数库是带缓存的。从第五章我们知道假如标准输出printf向终端设备输出,它就是行缓存的; 否则,它就是全缓存的。 当我们交互式的跑上述程序时, 我们只能够得到 pr

47、intf line的一个副本, 因为标准输出缓存被 newline刷新了。但是当我们将标准输出重定向到一个文件的时候,我们得到 printf line的两个副本。在第二种情况下,在fork之前的 printf 被调用一次,但当fork执行时,行在缓存中依然存在。因此缓存被复制到子进程当父进程的数据被复制到子进程时。此时父进程和子进程都有一个标准 I/O buffer,该行在 I/O buffer依然存在. 处于exit命令前的第二个 printf,恰好将它的输出加到existing buffer的后面。当每个进程都终止时,缓存的副本最终被刷新。,5.进程的建立与运行,创建新进程一般来说,在fo

48、rk()之后是父进程先执行还是子进程先执行是不确定的,这取决与内核使用的调度算法;,76,5.进程的建立与运行,父、子进程对打开文件的共享,77,v-node,每个打开文件或设备都有一个v-node structure ,其中包含文件的类型和在该文件上可执行操作的指针。对大部分文件来说, v-node 也包含该文件的 i-node。 v-node structure 当文件被打开始就从磁盘中读出,因此所有文件的相关信息都能够获得。 Linux 没有 v-node。取而代之的是一个通用的 i-node structure 。尽管完成方法不同,v-node 从概念上讲和 通用 i-node是一样的

49、. 两者都指向一个特定文件系统中的i-node structure.,这里很重要的一点是父子进程都有相同的文件偏移量。假设有某个进程fork了一个子进程,然后等待子进程执行完毕。同时假设父子进程在进程的执行过程中都向标准输出写数据。假如父进程将它的标准输出重定向(通过shell)到某个文件,那么当子进程向标准输出写入数据时,父进程的文件偏移量可以被子进程更新。 在这种情况下,子进程能够向标准输出写数据,而父进程需要等待它执行完毕;当子进程完成后,父进程能够继续向标准输出写入数据 ,写入的同时父进程知道写入的数据会加到子进程写入数据的后面。假如父子进程没有共享同样的文件偏移量,这种父子进程的交互

50、将很难完成,除非父进程做大量的工作。 假如父子进程都向同一个文件描述符写入数据,写入过程中没有任何的同步, 比如说父进程等待子进程的执行,他们的输出将会被打乱 (假设该文件描述符在fork之前就被打开)。 当然通常父子进程的交互过程中不会采取这种操作模式。,5.进程的建立与运行,父、子进程对打开文件的共享在fork()之后处理文件描述符有两种常见的情况:1. 父进程等待子进程完成;这种情况下,父进程不需要处理文件描述符. 当子进程终止时, 任何由父子进程共享的描述符,而且该描述符被子进程所读写过,那么被读写的文件描述符的偏移量会做适当更新。 2. 父、子进程各自执行不同的程序段,父、子进程各自关闭不需要使用的文件描述符,而不干扰对方使用的文件描述符。这在网络服务进程中经常使用。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报