全套PPT电子课件教案-第6章 UNIX系统内核.ppt_第1页
全套PPT电子课件教案-第6章 UNIX系统内核.ppt_第2页
已阅读5页,还剩135页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章 unix系统内核,6.1 概述 6.2 进程管理 6.3 文件系统 6.4 存储管理 6.5 设备管理,6.1 概 述,6.1.1 unix系统简介 1unix的诞生及发展 unix系统是一个通用的、多用户、多任务分时操作系统,于1969年诞生于美国贝尔实验室,是由ken.thompson和dennis.ritchie共同研制成功的。研制该系统的目的是为了在贝尔实验室内构造一个程序设计研究和开发的良好环境。unix系统包括unix操作系统内核和运行在内核之上的用户程序集、库,以及其它实用工具,unix操作系统内核为这些应用提供运行环境和各种系统服务。,贝尔实验室完成了unix的早期开发和发行,随着许多公司和大学对unix系统的青睐,市场上unix的各种版本广为流行,它们都支持一套基本的unix系统所拥有的接口、应用及其特征。这些版本在其内部实现接口的具体语义以及它们提供的“增值”特征方面千差万别,较为著名的有novell公司的system v release4(svr4),加州大学伯克利分校软件发行(4.xbsd)以及卡内基梅隆大学的mach,另外还有商业实现版本,如sun microsystem公司的sunos和solaris、ibm公司的aix以及惠普公司的hpux。,unix系统的研制和开发过程简介如下: 1969年,ken thompson开始在pdp7机上开发unix,1970年该系统投入运行。 1973年,dennis richie研制成c程序设计语言,并用它改写原来用汇编语言编写的unix,即第四版unix。 1973年,ken thompson和dennis ritchie合写“the unix time-sharing system“一文,提交美国计算机协会(acm)和第四次操作系统原理讨论会。该文经修改后刊登于1974年7月的cunmunication of acm杂志上,至此,unix操作系统正式向外披露。, 1975年,第六版(v6)正式发表,并开始广泛配备于各大学的pdp11系列机上。 1978年,第七版(v7)发表。 1979年,32 v版发表,该版本适用于vax11机。 1981年,at&t公司(贝尔实验室的母公司)发表s3(system )。 1983年,at&t公司发表system 。,unix在发展过程中产生了众多版本。这些版本在实现功能、采用技术、代码数量等方面都存在差异。早期的系统核心是无序结构,模块(函数)直接相互调用;而现在的unix版本都采用层次结构。为了便于系统移植,实现了功能的可裁剪性和规模的可伸缩性,mach系统采用了微内核结构和线程概念,支持client/server模型。,2unix版本简介 1) bsd 1974年12月,加州大学伯克利分校获得了unix许可证,在其后几年,bill joy和chuck haley等一组研究生为unix开发了几个实用工具,包括ex编辑器(后来发展为vi编辑器)和一个pascal编译器。他们将这些软件绑定成一个称作“伯克利软件发行(bsd)”,的软件包,于1978年春以每个许可证50美元出售。最初的bsd仅包括应用程序和实用工具,并没有对操作系统进行修改。bill joy还开发了c shell,它比bourne shell增加了作业控制、命令历史等功能。,1978年伯克利得到一台vax11/780以及贝尔实验室移植的unix/32v,vax11/780采用了32位体系结构,可以有4 gb的地址空间,而物理内存仅仅为2 mb。此时,ozalp baobaoglu为vax设计了一个分页式的虚存系统,并将其加入到unix系统中,这就是1979末发行的3bsd,是伯克利发行的第一个操作系统。 在技术方面,伯克利小组做出了许多贡献,包括虚拟存储、tcp/ip的集成、快速文件系统(ffs)、可靠的信号机制以及socket等先进技术,尤其是将tcp/ip网络协议族集成到了unix中,以此得到了美国国防部高级研究项目署(darpa)的资助,推动了internet的发展。在darpa的支持下,伯克利相继推出了4.0bsd4.4bsd。并通过伯克利软件设计公司(bsdi)将其进行了商业化,用伯克利开发的新源代码替代了原来的unix源代码。,2) system v system v是在贝尔实验室早期unix版本基础上发展起来的。at&t致力于拓广unix市场,分别于1982年和1983年发行了system 和system v, 1984年发行了system v release2 (svr2),1987年发行了svr3。许多商业unix的实现都是基于system v,较新版本是at&t公司和sun microsystem公司联合开发的svr4,于1989年首次发行。 在技术上,system v引入了许多新特征和新设施,“区”结构的虚存实现与bsd截然不同。svr3增加了进程间通信设施(共享内存、信号量和消息队列)、远程文件共享、共享库以及用于设备驱动程序和网络协议的streams框架;svr4则集成了svr3、4bsd、sunos以及xenix的一些特征,增加了新的功能,如实时调度、kon shell,并对streams系统进行了改进。,1991年,novell公司收购了at&t的unix实验室,联合投资开发svr4的桌面版,并集成了novell的netware pc机网络操作系统,称作unix ware,于1992年末发行。之后新的svr4发行,较新的是svr4.2/es/mp,支持多处理机并增强了系统安全性。1994年sun microsystem公司向novell公司购买了svr4代码使用权,其基于svr4的发行称作solaris,较新版本是solaris2.5。solaris提供了许多先进功能,包括全抢占多线程内核和对多处理机的全面支持等。,3) mach mach是由卡内基 梅隆大学的研究人员开发的一个全新的操作系统,支持4bsdunix编程接口,可以在单处理机或多处理机上运行,适用于分布式环境。mach的设计目标是微内核,内核仅提供必要功能的最小集,同时提供一个在用户级实现其它操作系统功能的框架,基本的方案是让微内核对外开放几个简单的抽象概念,然后用一组称为服务器的用户级任务提供大部分操作系统的功能。mach 3.0是第一个实现微内核的系统。,4) unix系统的商业版本 unix的不断发展吸引了许多计算机公司,他们迫切希望将unix商业化,出售自己的unix版本。这些版本都是以at&t公司的system v或伯克利的bsd为蓝本,将它们移植到自己的硬件上,并加上一些自己的“增值”功能,主要版本有基于4bsd的sun os和基于svr4的solaris、微软与sco合作发行的xenix、sco unix(svr3在386上的移植版本)以及ibm公司的aix、hp公司的hpux和digital公司的uitrix(digital unix)等。 此外,还有目前广泛流行的可运行于多种硬件平台、源码公开且可免费使用的linux操作系统。,6.1.2 unix系统的特点 unix系统在相当短的时间内取得这样大的成功,有其内部和外部原因。从外部观察,unix问世之时,正是人们开始普遍使用分时操作系统,并还在寻求一个功能齐备、使用方便、大小适中的系统之时,所以unix生逢其时。另外,这一系统是在pdp11系列机上开发出来的,而当时这种机型在世界各国已得到广泛应用,并曾占据小型机的主要市场,这就为unix的广泛配置创造了物质条件。这些外部原因都非常重要,但起决定性作用的因素是内部原因,即unix的小巧、稳定、简单内核、网络功能强等特点和性能决定了它的成败。与microsoft的windows nt相比,unix系统具有以下特点。,1开放性 开放性是指遵循国际标准规范,特别是遵循了开放系统互连osi国际标准的系统能彼此兼容,可方便地实现互连。人们普遍认为,unix是目前开放性最好的操作系统,它能广泛地配置在从微机到大、中型机等各种机器上,而且还能方便地将已配置了unix操作系统的机器互连成计算机网络,这也是它被广泛应用的有力证明。 2多用户、多任务环境 unix系统是一个多用户、多任务操作系统,它既可以同时支持数十个乃至数百个用户,通过各自的联机终端同时使用一台计算机,而且还允许每个用户同时执行多个任务。例如,在进行字符、图形处理时,用户可建立多个任务,分别用于处理字符的输入、图形的制作和编辑等任务。,3简洁的内核与丰富的核外程序有机结合 unix的设计思想着眼于向用户提供包含有多种工具,而且便于综合应用它们的程序设计环境,也就是构成一个能够提供各种服务的基础。在这样的设计思想提导下,unix系统在结构上分成两大层:内核和核外程序。 内核部分就是一般所说的unix操作系统,它包括进程管理、存储管理,设备管理、文件系统管理等几个部分。unix设计者对内核功能作了仔细考虑,对其中包含的数据结构和程序进行了精心设计,使其非常精干简洁。因此内核只需占用很小的存储空间,并且能够常驻内存,这就从根本上保证了系统能够以较高效率运行。,unix系统的核外部分包含有非常丰富的语言处理程序、系统实用程序和开发软件的工具性软件。在语言处理程序方面,unix提供有十几种常见程序设计语言的编译和解释程序,如c、fortran、c+、java等;语言开发工具有yacc、lex等。所有这些程序都作为文件存放在文件系统中,用户通过shell命令使用这些程序。正是这些系统软件给用户提供了相当完备的程序设计环境。 unix的系统设计特别注意了内核和核外程序的有机结合。内核向核外程序提供了充分而强有力的支持;核外程序则以内核为基础,灵活而恰到好处地运用了内核的支持。 两者结合起来作为一个整体,向用户提供各种良好的服务,其功能可以与某些大型系统媲美。,4树形结构的文件系统且将文件和设备统一处理 unix具有一个树形结构的文件系统,它由基本文件系统和可装卸的若干子文件系统组成。它既能扩大文件存储空间,又有利于安全和保密。 在unix中,文件是无结构的字符序列,用户可以按需任意组织其文件格式,对文件既可进行顺序读、写,也可随机存取。 另一方面,普通数据文件、文件目录表和外部设备都统一做文件处理,它们在用户面前有相同的语法语义,使用相同的保护机制,这样既简化了系统设计,又便于用户使用。,5系统用高级语言编写,可移植性好 unix操作系统和核外程序基本上用c语言编写,使得系统易于理解、修改和扩充,而且使系统具有非常良好的可移植性。unix的可移植性有两方面的含义,首先指的是unix系统易于移植到别的硬件系统上去;其次,在unix系统下开发的应用软件比较易于移植到其它配置有unix的计算机系统上去。,5系统用高级语言编写,可移植性好 unix操作系统和核外程序基本上用c语言编写,使得系统易于理解、修改和扩充,而且使系统具有非常良好的可移植性。unix的可移植性有两方面的含义,首先指的是unix系统易于移植到别的硬件系统上去;其次,在unix系统下开发的应用软件比较易于移植到其它配置有unix的计算机系统上去。,6强大的网络功能 早期的unix系统是在单机上运行的,彼此不能通信。伯克利受darpa资助,将tcp/ip协议族集成到4bsd中。目前unix系统支持许多网络接口、协议和远程过程调用(rpc)机制,集成了网络文件系统(nfs)和分布式计算环境(dce)等网络信息共享服务,为连网、网络应用和基于网络的应用软件开发提供了强有力的支持。,6.1.3 unix系统的核心结构 unix系统可分为三层:硬件层、核心层和应用层。靠近硬件的是核心,即unix操作系统常驻内存部分;用户在应用层通过核心对外提供的系统调用和库函数接口来使用核心的功能。图6-1展示出unix的三个层次。,图6-1 unix系统的内核结构,核心是unix操作系统的主要部分,它实现进程管理、存储管理、文件系统和设备管理等功能,从而为核外的所有程序提供运行环境。 unix核心可分为文件子系统和进程控制子系统两大功能部分。文件系统部分涉及操作系统中各种信息的保存,它相当于核心的“静态”部分。进程控制系统部分涉及操作系统中各种活动的调度和管理,通常以进程形式展现其生命活力。它相当于核心的“动态”部分。 文件子系统管理文件、分配文件空间、管理空闲空间、控制对文件的访问并为用户检索数据。进程通过一组特定的系统调用(如open、close、read、write、chmod等)与文件系统交互作用。,文件子系统利用缓冲机制访问文件数据。缓冲机制与块设备驱动程序相互作用以启动从核心向块设备写数据或者从块设备向核心传送(读)数据。文件系统也直接与字符设备驱动程序相互作用,这包括终端i/o和打印机输出等管理。 进程控制系统用于进程管理、进程通信、进程调度和内存管理等。控制进程的系统调用包括进程的创建、终止、执行、等待、空间扩充及信号传送等。 进程间采用多种形式进行通信,如sleep、wakeup,异步进程发信号,进程间消息同步传送等。,存储管理控制内存分配与回收。系统采用两种策略管理内存:对换和请求分页。根据系统中物理内存空间的使用情况,将进程映象在内存和辅存(磁盘)之间换入/换出。利用请求分页技术提供虚拟存储器。 进程调度模块为进程分配cpu。为保证各分时用户进程都得到公平的运行机会,进程调度采用多级反馈队列轮转法。 核心底层的硬件控制负责处理中断和与机器通信。外部设备(如磁盘或终端等)在完成某个工作或遇到某种事件时会中断cpu执行,由中断处理系统进行相应分析、处理。处理之后将恢复被中断进程的执行。,6.2 进 程 管 理,6.2.1 unix进程映象和进程状态 1unix进程映象 在unix中,进程被描述为映象(image)的执行,而映象则是计算机的执行环境,进程映象包括一个存储映象、通用寄存器的值、打开文件的状态以及当前目录等。 system v中进程的存储器映象包括正文段、数据段、共享内存段、系统栈、用户栈和进程控制块(pcb)。,正文段是进程映象中可由多个进程共享的区域,其中包括纯代码形式的程序和常量等。正文段从进程虚拟地址空间的0单元开始,在执行期间这个段受到保护。 数据段中含有属于进程私有的程序和数据,可被用户态进程读、写或执行。该段的大小可通过一个系统调用加以扩充或压缩。 共享内存段为多个进程共享同一数据区提供了可能。该段为可选择部分,当进程需要与其它进程共享某一内存段时,使用系统调用将其连入本进程,用过后又可以使其脱离本进程。,进程的用户栈和核心栈分别是进程在用户态和核心态下运行时的工作区,主要用于函数调用时传递参数、保留现场、存放返回地址以及为局部变量提供存储区等。核心栈仅为核心态进程所存取。当进程在用户态方式下运行时,其核心栈是空的。这两个栈是自动创建的,其大小由核心在进程运行期间动态调整。 进程控制块分两个部分:常驻内存部分和非常驻内存部分,前者构成的数据结构为proc,后者构成的数据结构为user。需要注意,proc中的表项对核心来说必须是可存取的,而user区的字段只能由正在运行的进程来存取,也就是说,只有当前占据cpu的进程才能访问属于当前进程私有的user区。,属于不同进程的user区形式上有相同的虚地址,但其物理地址是随不同的运行进程而变化。每个进程都有一个专用的user区,核心访问user区时就好像系统中仅有一个user区,即当前进程的user区。根据进程页表,通过地址映射机构来访问与当前进程相联系的user区。如果页表不同,即使核心用相同的虚地址访问user,但实际物理地址还是不一样的。进程在核心态运行时能够访问user区,但在用户态却不能。user区在某种程度上决定了系统中运行的进程的上下文。下面给出proc结构和user结构的说明。,(1) proc结构中的主要域如下: 进程标识:每个进程有一个惟一的进程id(pid)。 用户标志号(uid):确定不同进程的特权。 当前进程和它的user结构在内存或外存上的位置。 进程状态。 进程睡眠原因,即等待事件的描述字。 调度优先级和相关信息,包括优先数、进程使用cpu的情况、用户设置的优先数偏置值等。核心利用这些参数来确定调度次序。, 调度队列、阻塞队列或睡眠队列的前、后向指针。 信号处理信息:各种信号,包括忽略信号、阻塞信号、已发送信号及已处理信号的掩码。 进程的大小。 将这个结构链接到活动进程、空闲进程或僵尸进程队列的指针。,(2) user结构中的主要区域如下: 指向本进程proc结构的指针。 真实和有效的用户标志号。 当前系统调用的参数、返回值或错误状态。 信号处理程序及处理方式表。 由程序头获得的信息,如正文、数据、堆栈大小和其它内存管理信息。 打开文件描述符表,记载本进程打开文件的情况。 当前目录和当前根,描述了进程文件系统的环境。,图6-2 unix进程映象, i/o参数,它们说明传送数据的总量、用户空间中源(或目标)数据区的地址,用于i/o的文件读、写的起始位置等。,2unix进程状态 unix进程的执行也是一个走走停停、动态的过程,该过程由进程状态的变化来刻画。unix的进程状态可分为10种。图6-3表示了unix system v进程的状态及其变化。各种进程状态的含义如下: (1) 用户态运行(在cpu上执行用户程序); (2) 核心态运行(在cpu上执行核心程序); (3) 在内存就绪(具备运行条件,只等核心调度它取得cpu控制权); (4) 在内存睡眠(不具备运行条件,在内存中等待某一事件发生);,(5) 在外存就绪(就绪进程被对换到外存上); (6) 在外存睡眠(睡眠进程被对换到外存上); (7) 在内存暂停(因调用stop程序而进入跟踪暂停状态,等待其父进程发送命令); (8) 创建态(新进程被创建,但尚未创建完毕的中间状态); (9) 在外存暂停(处于跟踪暂停状态的进程被对换到外存上); (10) 终止态(进程终止自己)。,图6-3 进程状态及其变化,unix为进程设置了两种运行状态:一种是核心态(kernel mode),另一种是用户态(user mode)。如果当前运行的是用户程序,那么对应进程就处于用户态运行;如果出现系统调用或者发生中断事件,就要运行操作系统(即核心)程序,进程状态就变成核心态运行。,6.2.2 进程控制 1进程的创建(fork) 与多数操作系统对进程的管理相似,unix系统中各个进程构成了树形的进程族系(见图6-4)。在unix系统初启时,生成0# 进程,由它创建1# 进程及其它核心进程(如页面淘汰进程),然后1# 进程又为每个终端生成一个注册进程和一个shell进程,分别管理用户注册和执行shell命令解释程序。用户和系统交互作用过程中,由shell进程打入的命令创建若干进程,每个子进程执行一条命令。执行命令的子进程也可再创建子进程。这棵进程树除了同时存在的进程数受到限制外,树型结构的层次可以不断延伸。,在unix操作系统中,除0# 进程外,其它进程都是用系统调用fork创建的。调用fork的进程是父进程,被生成的进程是子进程。调用fork的形式为: pid=fork(); 父、子进程从fork返回的值是不同的:父进程返回的值是子进程pid标志号,而子进程的返回值是0。,图6-4 进程创建的层次关系,fork算法要做下列操作: 取一个空闲的proc表项,指定惟一的pid号码; 标记子进程状态为“正被创建”; 从父进程的proc结构中复制数据到新建子进程的proc结构中; 增加当前目录i节点和“更改过的文件根”(如可用的话)上的计数值; 增加系统打开文件表中的计数值; 在内存建一个父进程映象的副本(包括user结构、正文段、数据段和栈); 把各寄存器内容构成的系统环境记入子进程的运行环境中,以后子进程被调度,就从此开始执行; 将子进程状态改为“就绪”,子进程的pid号返回给父进程。,2进程的等待(wait) 父进程创建子进程的目的往往是让子进程替自己完成某项工作。因此,父进程创建子进程之后,通常等待子进程运行终止。父进程用系统调用wait(stat_addr)等待它的一个子进程终止,其中stat_addr是终止地址码。 wait算法是: 如果父进程没有子进程,则出错返回; 如果发现有一个终止的子进程,则取出子进程的进程号,把子进程的cpu使用时间等加到父进程上,释放子进程占用的proc表项,以供新进程使用; 如果发现有子进程,但都不处于终止态,则父进程睡眠,等待由相应信号唤醒。,3进程的终止(exit) 在unix系统中,进程主要是作为执行命令的单位运行的,这些命令的代码都以系统文件形式存放。当命令执行完后希望终止自己时,可在其程序末尾使用系统调用exit(status),其中status被称为终止码。它是终止进程向父进程传送的参数,父进程执行wait时可取得该参数。用户进程也可使用exit来终止自己。其实现算法如下: 忽略所有的信号; 如果本进程是与控制终端相关的进程组中的“首领”,则向该进程组的所有成员发送“挂起”信号,把所有成员的进程组号置为0;, 关闭全部打开文件; 释放当前目录; 释放与该进程有关的各分区及其内存; 做统计记录(全局帐目文件); 置进程状态为“终止态”; 指定它所有子进程的父进程id为初启进程(1#); 如果有任何子进程终止了,则向1# 进程发出子进程终止的信号; 向它的父进程发送子进程终止的信号; 执行进程调度。,4进程映象的更换(exec) 子进程被创建后,通常处于“就绪态”,以后被调度选中才可运行。由于创建子进程过程中是把父进程的映象复制给子进程,所以子进程开始执行的入口地址就是父进程调用new-proc函数(由fork调用)建立子进程映象时的返回地址,此时二者的映象基本相同。如子进程不改变其映象,就必然重复父进程的过程。为此,要改变子进程的映象,使其执行另外的特定程序(如命令所对应的程序)。,改换进程映象的工作很复杂,是由系统调用exec实现的,它用一个可执行文件的副本来覆盖该进程的内存空间。其基本算法如下: 取文件i节点; 验证文件的可执行性,即用户有权执行它; 读文件头,检查该文件是否可执行; 根据文件头中的信息,对隶属该进程的全部分区(正文段、数据段等)分配新的分区;, 将这些分区链接到进程;如果适宜,则把分区装入内存。 把exec参数复制到新的用户栈区; 设置用户寄存器(如用户栈指针、程序计数器等),以便返回到用户态; 释放文件的i节点。,6.2.3 进程调度 1调度的策略、时机和算法 unix系统的进程调度采用基于动态优先级的多级反馈队列轮转法,即从可运行的优先数最小(优先权最大)的队列中选取一个进程映象投入运行。核心为该运行进程分配一个时间片,当时间片用完后,cpu被另外的进程抢占,而原进程被送回次高优先级队列的末尾,核心动态调整用户态进程的优先级。,核心进行进程调度的时机(原因)有以下几种情况: (1) 进程调用sleep程序; (2) 进程终止; (3) 进程在内存中暂停; (4) 进程从系统调用返回到用户态时,但它并不是最适宜运行的进程; (5) 核心处理完中断后,进程回到用户态,但存在比它更适宜运行的进程。,进程调度是由swtch过程实现的,系统中所有进程对cpu的使用和放弃都要通过执行swtch才行,swtch过程是进程0的一部分。 调度进程的算法如下: 调度进程算法 输入:无 输出:无 while(没有进程被选中执行) for(所有在就绪队列中的进程) 选出优先级最高且在内存的一个进程;,if(没有合适进程可以执行) 机器作空转; /*当中断发生后,使机器摆脱空转*/ 从就绪队列中移走该选中进程; 切换选中进程的上、下文,令其运行; ,2进程优先级的确定和优先数的计算 unix进程调度的关键是如何决定进程的优先权或优先数。确定进程优先数的目标是提高用户和系统交互作用的速度,提高系统资源的使用效率,反映用户的类型以及他们对有关作业运行优先程度的要求。 unix system v中进程的优先级分为两大类:用户优先级和核心优先级类。每一类又包含若干个优先级,每一个优先级在逻辑上都对应一个进程队列,如图6-5所示。,图6-5 unix进程优先级,在unix系统中,进程的优先级用相应的优先数来表示:优先数越小,其优先级越高。 从图6-5中可以看出,核心态优先级在优先级阈值之上,而用户态优先级在优先级阈值之下,各种核心事件的优先级高于用户进程的优先级。图中优先级的级别从下至上依次升高。 进程的优先数是动态改变的,而且是在特定的进程状态下发生的。核心用两种方式改变进程的优先级:对核心态进程设置优先数和对用户态进程计算优先数。,(1) 核心态进程因等待某一事件而调用sleep程序去睡眠时,核心根据该进程睡眠的原因为它设置一个确定的优先数。 (2) 当系统调用执行结束,进程由核心态返回用户态以及进程正在用户态下运行时,由时钟处理程序通过计算方式来调整其优先数。system v进程优先数计算公式为: ppri=pcpu/2+puser+pnice+nzero,其中: pcpu为进程最近一次使用cpu的时间。正占有cpu的进程每个时钟周期对其pcpu加1(80)。另外,每秒对所有进程执行pcpu/2。 pnice是系统允许用户设置的一个计算进程优先数的偏移值,但仅有权将其设置为039中的一个数。一旦设置后,普通用户仅能使其增加。 puser和nzero是两个常数,分别为25和20,称为基本用户优先数的分界(即阈值)。,以上进程优先数计算方法体现了如下策略:正在运行的进程占用cpu的时间越久,其优先数越大,优先级越低;内存就绪态进程排队时间越长,其优先数逐渐降低,优先级升高。这样就实现了反馈作用,防止运行进程总是占用cpu。,3进程上、下文的切换 当核心进行了进程调度,选中了一个新的进程需要运行时,将引起进程上、下文的切换。在unix系统中,进程上、下文的切换过程分成以下四步: (1) 先确定是否要进行上,下文的切换; (2) 利用save_context函数保存当前进程的上、下文; (3) 由调度程序按一定的策略,选择一内存就绪进程; (4) 用resume_context函数恢复被选中进程的上、下文,此后便进入进程上、下文的执行。,6.2.4 进程通信 unix system v中提供了丰富的进程工具,除基本工具sleep和wakeup、信号、管道和进程跟踪外,又增加了命名管道(fifo文件)、消息缓冲、共享内存和信号量等通信机构。由此,通常unix系统为进程之间的通信提供了多种工具: 利用基本通信工具sleep和wakeup来实现核心态进程之间的通信(同步)。 利用内核提供的信号(signal)机制来实现同一用户的各个进程之间少量信息的传递。, 利用文件系统生成pipe机构来实现进程通信(无名管道),为同父的子进程之间提供大量信息的传输;利用fifo(有名管道)实现不同父进程之间的管道传输。 消息缓冲。 共享内存段。 信号量。,1sleep和wakeup sleep和wakeup是unix核心的两个程序,它们可以实现进程状态的转变:sleep将进程状态从“核心态运行”变为“在内存睡眠”,使之让出处理机;而wakeup把进程状态从“睡眠”变为“就绪”(在内存或者在外存)。这两个程序是核心内部实施进程同步与互斥的基本工具。 在核心态运行的进程因所需条件不具备时,则调用sleep(chan,disp)进入睡眠状态。其中参数chan是睡眠原因,另一个参数disp是由核心指定的优先数,其值越小,对应的调度优先权越高。,wakeup程序唤醒在因同一原因而睡眠的所有进程,而不是一次只唤醒一个进程。这样,执行进程调度时,优先级最高的被唤醒进程可得到运行。如运行时发现缺少先前等待的事件,它则重新进入睡眠态。运行进程完成某一事件(如i/o完成,释放缓冲区等)后,往往利用wakeup(chan)的形式去唤醒睡眠进程,其中参数chan表示睡眠地址(即睡眠原因)。,2信号机制 异步进程可以通过彼此发送信号来实现简单通信。系统预先规定若干个不同类型的信号(如unix svr4中设置32种信号),分别表示发生了不同的事件,每个信号对应一个编号。当运行进程遇到相应事件或者出现特定要求时(如进程终止或运行中出现某些错误,如非法指令、地址越界等),就把一个信号写到相应进程proc的p-sig信号项中。接收信号的进程在运行过程中要检测自身是否收到了信号,如果已收到信号,则转去执行预先规定好的信号处理程序,其入口等信息存放在user中。处理之后,再返回原先正在执行的程序。进程之间利用信号机制实现通信的过程如图6-6所示。,图6-6 利用信号实现进程间通信,表6-1 信号与硬中断的比较,信号处理机构是系统中围绕信号的产生、传送和处理而构成的一套机构。该机构通常包括三部分: (1) 信号的分类、产生和传送; (2) 对各种信号预先规定的处理方式; (3) 信号的检测和处理。,通常信号可分为进程终止、进程执行异常(如地址越界、写只读区、用户执行特权指令或硬件错误)、系统调用出错(如所用系统调用不存在、pipe文件有写者无读者等)、报警信号等。系统一般也给用户留出自己定义信号的编号。 当发生上述事件后,系统可以产生信号并向有关进程传送。进程彼此间可用系统提供的系统调用(如system v中的kill)发送信号。信号要记入接收进程的proc中,以备接收进程调度运行时检测和处理。,进程接到信号后,在一定时机(如中断处理末尾)作相应处理。可有三种处理方式:接收进程终止(往往是在用户态运行时出现了故障)、忽略信号或者执行相应处理程序。 信号机构为进程间实现预定的相互控制提供了一种可行方式,unix中父进程对子进程的跟踪处理机构是在此基础上扩充而成的。当然,信号机构也增加了系统的复杂性。,3管道 管道(pipe)是unix对os的重要贡献之一。本质上,管道是一个单向的、先进先出的共享文件。写进程在管道的尾端写入数据,读进程从管道的首端读出数据。数据读出后,从管道移走,其它读进程不能再读到这些数据。进程试图读空管道时被阻塞。同样,管道已经写满时,进程想写入数据时亦将被阻塞。图6-7示意了通过管道的数据流。 1) 管道的类型 管道有两种类型,一种是pipe,称无名管道,用于同父的两个子进程之间传递较大量的信息。另一种是命名管道,也称为有名管道,用于实现不同父进程之间的数据传递。,图6-7 通信管道的数据流,2) 管道的建立与读写 无名管道与有名管道的建立方法不同。进程通过系统调用pipe建立无名管道,此进程的子进程就可对此管道进行读写共享。 系统调用pipe(fdp)中的fdp为整型数组指针,包含分别用于管道读写的两个文件描述字fd。核心创建管道时,为管道分配一个i节点、一对文件描述字和相应的系统打开文件表项(一个用来从管道读,一个用来向管道写),进程不必知道它们读/写的是普通文件还是管道。,一个命名管道是一个文件,语义上和无名管道一样。但这个文件有目录项并可通过路径名来存取,用与打开普通文件的同样方式打开命名管道,因此关系不密切的进程也可以互相通信。命名管道在文件中永久存在,而无名管道是临时的,对于命名管道,首先必须先建立,读写之前先打开,当文件不再需要时要删除。 命令mknod(path,mode,dev)用于建立一个目录文件、特别文件或命名管道。其中path为新建文件路径的指针,新文件的属性根据mode进行初始化。当建立命名管道时,参数dev被忽略。使用mknod建立的命名管道并不打开它。,命令open(path,oflg)用于打开path指向的文件,并根据oflg的值来设置该文件的状态标志。path为文件路径名指针。打开一个命名管道与打开一个普通文件没什么差别。只是通信的发送方用“owronly”(只写)方式打开,另一方则用“ordonly”(只读)方式打开。 通信结束后要关闭命名管道,但文件本身并没有消失,以后可以继续打开使用。 命令unlink(path)可以删除一个命名管道,path为被删除文件路径名指针。 进程间使用命名管道实现一次通信有三次同步,如图6-8所示,第一次是打开同步,第二次是读写同步,第三次是关闭同步。这些同步均由系统完成。,图6-8 a、b两进程使用命名管道完成一次通信的过程,4消息缓冲机制 所谓消息就是一组结构化的信息,包括以下内容:发送消息的进程名、消息长度、消息正文、下一个消息缓冲区指针等。消息缓冲通信机制的基本思想是:由系统管理一组缓冲区,其中每个缓冲区可以存放一个消息。当一个进程要发送消息时,先要向系统申请一缓冲区,然后把信息写进去,接着再把缓冲区送到接收进程的一个消息队列中。接收进程则在适当的时候从消息队列中取用消息,并释放有关缓冲区。 system v的消息缓冲机构除能实现上述通信功能外,又做了一些扩充,使用方式也稍有差别,主要有以下几点:, 消息队列设在系统内部并由系统管理,而不是设在每个进程头上。每次通信前双方都要申请消息队列,用后释放。 消息正文的长度不固定,可长可短。 消息的发送方和接收方不固定。通信双方可以使用同一个消息队列,也可以使用若干个不同的消息队列。 接收进程可以有选择地接收某个队列中的消息。 只有被授权的用户才能在通道上发送或接收消息。,进程通过系统调用msgget( )来创建或获得一个消息队列;通过msgsnd( )调用把消息放入队列中;进程读消息时,使用msgrcv( )调用将消息从队列中移去。,图6-9 消息队列的使用,5共享存储区(共享内存段) 共享内存区域是被多个进程共享的一部分物理内存,进程可以把这些区域映射到它们地址空间中的任一合适的虚拟地址范围。这些地址范围对每一个进程来说可以是不同的,如图6-10所示,映射后这些区域就可以像其它任何内存位置那样被访问。因此,共享内存机制提供了进程共享数据的最快的方法。进程向共享内存区写入了数据,那么共享这个区域的所有进程可以立即看见共享区域中新的内容。,system v系统核心为共享内存段的进程提供了四个系统调用(省去了其中的参数)。 shmget( ):创建或打开一个共享内存段(但不能访问共享内存段); shmat( ):将共享内存段与调用者的虚拟地址联系起来; shmdt( ):将共享内存段与调用者的虚拟地址断开; shmctl( ):查询、设置和改变共享内存段的属性与状态。,图6-10 通过共享内存实现进程通信,6信号量 system v中的信号量机构对传统的基于p、v操作的信号量机制做了很大扩充,一次可以对一组信号量进行相同或不同的操作;每个操作不限于p、v的减1或加1动作,而是可以加减任何整数;根据用户指示,在进程终止时可以消除所有被它操作过的信号量的影响。相应的系统调用有(省去了其中的参数): (1) semget( ):申请一组信号量; (2) semop( ):对指定的信号量集合执行信号量操作,包括信号量值的增减、恢复、挂起进程(使其睡眠)等。 (3) semctl( ):提供对信号量集合中某个信号量的多种控制,包括读取或设置信号量当前值,删除信号量等功能。,6.3 文 件 系 统,6.3.1 文件系统结构 在unix系统中,文件信息是以物理块为单位存放在介质上的,每块的长度为1 kb(或512 b)。unix system v文件系统的构造形式如图6-11所示。(不同类型的文件系统有不同的构造形式)。,图6-11 文件系统空间的构造,图6-11中,0#块是系统引导块,不属于文件系统管辖,只有root文件系统才有引导程序放在这里,其余一般文件系统都不使用引导块。1#块是文件的专用块(也称作超级块),它既是文件系统控制块,也是空闲块和i节点等资源管理表;2#k+1#块,共k块(k值由系统配置给定),作为i节点区;k+2#n#块为文件存储区;n+1#m#块为进程对换区,保留对换到外存的进程映象,它不属于文件系统管辖(其中,n和m的值也由系统配置指定)。, 文件系统大小i节点所占盘块数、文件系统盘块总数。 空闲盘块数目s_nfree,它是当前可被直接分配使用的盘块数。 空闲块索引表s_free50,其中放有当前可用的盘块号。 空闲i节点数目s_ninode。 空闲i节点索引表s_inode100。 封锁标记(在维护空闲队列期间封锁)。 专用块修改标记。 其它信息,如总空闲数、文件系统名称、文件系统状态等。,6.3.2 文件控制块i节点的分配与释放 1i节点(i_nodes) unix文件系统的i节点起文件控制块的作用,利用这种数据结构对文件进行控制和管理。i节点有静态和动态两种形式:静态形式存放在磁盘的专设i节点区中;而动态形式又称为活动i节点,它存放在系统专门开设的活动i节点区(在内存)中。 盘i节点(即静态形式)是一种数据结构,其定义形式如下(用c语言描述):,struct dinode ushort di_mode; /*文件属性和类型*/ short di_nlink; /*文件连接计数*/ ushor tdi_uid; /*文件主标号*/ ushort di_gid; /*同组用户标号*/ off_t di_size; /*文件字节数*/ char di_addr40; /*盘块地址*/ time_t di_atme; /*最近修改时间*/ time_t di_ctime; /*创建时间*/ ;,活动i节点除了具有盘i节点的主要信息外,又增添了下列反映该文件活动状态的项目: (1) 散列链指针(i_forw和i_back)和自由链指针(av_forw和ay_back),构成两个队列。利用散列链可加快检索i节点的速度。散列值利用i节点号和其所在逻辑设备号求得。 (2) 状态标志(i_flag),表示该i节点是否被封锁,有无进程等待它解除封锁,是否被修改过,是否是安装文件系统的节点等。 (3) 访问计数(i_count),表示在某一时刻该文件被打开后进行访问的次数。当它为0时,该i节点被放到自由链中,表示它是空闲的。,(4) i节点所在设备的逻辑号(i_dev),表明文件系统可由多台逻辑设备构成。 (5) i节点号(i_number)。它是对应的盘i节点在盘区的顺序号。 另外还有指针项,分别指出安装设备i节点、相关数据流、多文件映象盘块号等。 每一个文件对应唯一的盘i节点,每个打开的文件都有一个对应的活动i节点。,2活动i节点的分配与释放 用户打开一个文件时,必须为该文件在活动i节点表中申请一个表项,并且进行相应登记。其实现过程是: 将设备号和i节点号映象到散列队列,并在该队列中检索该i节点; 若未找到,则从自由链中分配一项并封锁它; 把对应的盘i节点复制到该项中,并把这个活动i节点放到相应的散列队列中。,当关闭文件时,要释放它的活动i节点,其执行过程是: 封锁该i节点,减少其访问计数; 若访问计数降为0,且i节点被修改过,则把它写回到盘区,该活动i节点被链入空闲链; 若对应文件的连接计数也为0,则核心同时释放文件所用的全部盘块和盘i节点项(实际上是删除该文件)。,3空闲i节点的分层分配与释放 对于一个新建的文件要为它分配一个盘i节点。在文件系统中盘i节点是线性排列的。如果一个盘i节点的di_mode为0,则表明它是空闲的i节点。在专用块的s_inode100这个数组中放有可直接使用的空闲i节点号。 分配空闲i节点的过程是: 确认没有其它进程封锁空闲i节点链表; 若该链表不空,则分配末尾一个i节点号,并分配一个活动i节点表项,并置初值;, 若该表空了,则线性检索盘上的i节点区,把空闲i节点号(di_mode=0且未在活动i节点区中出现)填到专用块的空闲i节点索引表中,直至填满该表(最多可容纳100个)或检索到末尾,然后再分配i节点。 为了改善查找效率,当把空闲i节点索引表填满时,就记下检索盘i节点区的位置。下次重新找空闲i节点时,就从这个位置开始依次向下找。,在删除文件时,除了释放文件的物理盘块外,还要释放文件的i节点。其过程是: 若专用块被封锁,则立即返回; 若未被封锁,则把它的号码放入数组s_inode中(以s_ninode为下标),s_ninode加1; 若s_inode已满,则后面相继释放的i节点不再登记,但要相应调整记载下次开始检索的位置。,6.3.3 文件的打开与关闭 1用户打开文件表和系统打开文件表 为了打开文件和便于共享管理,核心设置了两个数据结构(见图6-12): 用户打开文件表:又称为用户文件描述字表或进程打开文件表,它是user结构中的一个指针数组,各指针分别指向对应的系统打开文件表项。 系统打开文件表:又称为文件表,是系统设置的一个共同数据结构组成的数组。各结构中含有指向对应活动i节点的指针、共享计数以及读写位移等信息。,图6-12 两个进程打开文件后的数据结构,设置用户打开文件表的目的主要有两个:一个是让各个进程掌握它当前使用文件的情况,不要同时打开过多文件;另一个是加速对文件的查找速度。该数组的下标值就是文件描述字fd的值。由fd作索引来访问打开的文件,比直接用文件名查找要快得多。 核心设置系统打开文件表的原因是:一个文件可以被同一进程或不同进程、用相同的或不同的路径名、以相同的或不同的操作要求同时打开。在unix中,普通文件是一个无结构的字符流,文件的每次读写都要由一个读写指针指示位置。对于具有父子关系的进程,它们可利用同一读写指针;而对于无父子关系的进程来说,各自要用不同的读写指针。为此,系统在内存开辟了一个系统打开文件表,共100项。,2打开文件 通常,文件的使用规则是先“打开”,后使用。打开文件的目的就是建立从用户文件管理机构到具体文件的控制块(i节点)之间的一条联络道路。利用这种通路可加速系统对文件的检索、权限验证、读写指针共享等操作,改善文件系统的性能。 打开文件的过程是: 按照给定的文件名在目录结构中查找该文件,得到相应的i节点号; 检查打开文件的合法性(权限),如权限不对,则不能打开文件;, 如果该文件没有在活动i节点区中,则为它分配一个活动i节点; 在系统打开文件表中分配一项,使它的指针指向该文件的活动i节点; 在该进程的用户打开文件表中分配一个空项,使它指向对应的系统打开文件表项; 最后返回文件描述字“fd”。,系统创建每个进程时,自动为它打开三个标准文件,这就是用户打开文件表中前三项所对应的文件:fd为0的项对应标准输入文件(stdin,通常是键盘),1对应标准输出文件(stdout,通常是显示器),2对应标准错误输出文件(stderr,通常也是显示器)。在unix系统中,对用户来说所有设备都统一按文件进行处理。由于这三个

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论