[架构之路-162]-《软考-系统分析师》-3-作系统基本原理-进程管理
目录
前言:
3 . 1 操作系统概述
3.1.1 操作系统的类型
2 . 批处理系统
3 . 分时操作系统
4 . 网络操作系统
5 . 分布式操作系统
6 . 嵌入式操作系统
3.1.2 操作系统的软件结构
1 . 整体结构
2 . 层次结构
3 . 客户/服务器结构
4 . 面向对象结构
3 . 2 进程管理
3.2.1进程的状态(单进程状态)
1 . 三态模型
2 . 五态模型
3 . 2 . 2 信号量与P V 操作(进程间合作)
3. 2. 3 死锁问题
1 . 死锁预防:在死锁没有发生前就采取手段,避免进程满足上述4个条件
2 . 死锁避免 (最常见高效的做法)
3 . 死锁检测和解除
3. 2. 4 线程管理
1 . 线程的实现方式
2 . 与进程的比较
3 . 多线程模型
前言:
系统分析师必须具备扎实的理论知识和丰富的实际项目经验,而操作系统作为计算机科学最为基本的理论基础和分支领域之一,是系统分析师必须重点掌握的知识。
操作系统是计算机系统中最重要、最基本的系统软件,它位于硬件和用户之间,一方面能向用户提供接口,方便用户使用计算机;
另一方面能管理计算机软硬件资源,以便合理充分地利用它们。从资源管理的角度来看,它是计算机系统中的资源管理器,负责对系统的软硬件资源实施有效的控制和管理,提高系统资源的利用率;
从方便用户使用的角度来看,操作系统是一台虚拟机,它是计算机硬件的首次次扩充,隐藏了硬件操作细节,使用户与硬件细节隔离,从而方便了用户的使用。
3 . 1 操作系统概述
操作系统是控制和管理计算机软硬件资源,以尽可能合理、有效的方法组织多个用户共享多种资源的程序集合。它具有并发性、共享性、虚拟性和不确定性等特点,一般的操作系统都具有处理机管理、存储器管理、设备管理、文件管理和用户接口等5 种主要功能。
(1) CPU处理机管理。
负责对处理机的分配和运行实施有效的管理。在多道程序环境中,处理机的分配和运行是以进程为基本单位的。因此,处理机管理可归结为进程管理。
(2) 存储器管理。
存储器管理的主要任务是对内存进行分配、保护和扩充。
(3) IO设备管理 (特殊的内存)
设备管理应具有设备分配、设备传输控制和设备独立性等功能。
其中设备分配是指根据一定的原则对设备进行分配,为了使设备与主机并行工作,常需采用缓冲技术和虚拟技术;
设备传输控制是指实现物理的输入/输 出 ( Input / Output , I / O )操作,即启动设备、中断处理、结束处理等;
设备独立性是指用户向系统申请的设备与实际操作的设备无关。即使用一个通用的设计接口。
(4) 文件管理 (特殊的内存设备)
负责对文件存储空间进行管理,包括存储空间的分配和回收, 目录管理、文件操作管理和文件保护等功能。
(5) 用户接口(用户)
为了使用户能灵活、方便地使用计算机和系统功能,操作系统还提供了一组友好的使用其功能的手段,称为用户接口,它包括两大类,分别是程序接口和操作接口。用户通过这些接门能方便地调用操作系统的功能,有效地组织作业和处理流程,并使整个系统能高效地运行。
3.1.1 操作系统的类型
一般来说,操作系统可分为单用户操作系统、批处理系统、分时系统、实时系统、网络操作系统、分布式操作系统、并行操作系统和嵌入式操作系统等。
1 . 单用户操作系统
单用户操作系统的基木特征是在一台处理机上只能支持一个用户程序的运行,系统的全部资源都提供给该用户使用。目前,多数微机/单片机上运行的操作系统都属于单用户操作系统。
2 . 批处理系统
批处理系统也称为作业处理系统。在批处理系统中,作业成批地装入计算机中,由操作系统在计算机的输入井将其组织好,按一定的算法选择其中的一个或多个作业,将其调入内存并使其运行。运行结束后,把结果放入磁盘输出井,由计算机统一输出后交给用户。
批处理操作系统中配置了一个监督程序,在该监督程序控制, 系统能够对一批作业进行处理。其基木特征是“批量”,把作业的吞吐量作为主要目标,同时兼顾作业的周转时间。批处理操作系统又分为单道批处理系统和多道批处理系统。单道批处理系统在内存中只能存放一道作业,大大减少了人工操作的时间,提高了机器的利用率。但是,对于某些作业来说,当它发出 I / O 请求后,中央处理单元 (CentralProcessing Unit , C P U ) 必须等待 I / O 的完成,而由于 I / O 设备的低速性,从而使 C P U 的利用率很低。为了改善 C P U 的利用率,引入了多道程序设计技术,就形成了多道批处理操作系统。
在多道批处理操作系统中,不仅在内存中可同时有多道作业在运行,而且作业可随时被调入系统,并存放在外存中形成作业队列。然后,由操作系统按一定的原则,从作业队列中调入一个或多个作业进入内存运行。多道批处理系统具有资源利用率高和系统吞吐量大的优点,但它将用户和计算机操作员分开,使用户无法直接与自己的作业进行交互。另外,作业要进行排队,依次处理,因此,作业的平均周转时间较长。
3 . 分时操作系统
为了解决批处理系统无法进行人机交互的问题,并使多个用户能同时通过自己的终端以交互方式使用计算机,共享主机中的资源,为此,系统中采用了分时技术,即把 C P U的时间划分成很短的时间片,轮流地分配给各个终端作业使用。这种操作系统就称为分时操作系统,简称为分时系统。
对于某个作业而言,若在分配给它的时间片内,作业没有执行完毕,也必须将 C P U交给下一个作业使用,并等下一轮得到 C P U 时再继续执行。这样 , 系统便能及时地响应每个用户的请求,从而使每个用户都能及时地与自己的作业交互。分时系统具有多路性、独立性、及时性、交互性和同时性等特征。
4 . 网络操作系统
网络络操作系统是指在计算机网络环境下,具有网络功能的操作系统。计箅机网络是一个数据通信系统,它把地理上分散的计算机和终端设备连接起来,达到数据通信和资源共享的目的。
网络操作系统最主要的特点是网络中各种资源的共享,以及各台计算机之间的通信。有关数据通信与计算机网络方面的详细知识,将在第4 章中介绍。
备注:
在非网络操作系统的情形下,每个操作系统管理自己的资源,操作系统之间是相互隔离的,操作系统之上的应用程序之间是不能直接相互访问。在网络操作系统的情形下,不同操作系统之间的应用程序,可以通过网络操作系统提供的服务,实现不同操作系统之间的资源的共享以及应用程序之间通过共享资源进行通信。
这系统软件中间件是类似的:普通的中间件,可以实现同一个操作系统之上的应用程序之间的相互通信、共享共享操作系统的所有软硬件资源。而支持网络通信的中间件,可以为运行在其上的应用程序,提供跨操作系统、跨网元、板卡之间的资源共享和相互通信的需求。
5 . 分布式操作系统
分布式系统是由多台计算机组成的系统,系统中若干台汁算机可以相互合作,共同完成同一个任务。在分布式系统中,任意两台计算机之间都以利用网络通信来交换信息,系统中的资源(所有计算机的资源称为系统资源)为所有用户共亨。分布式系统的优点是各节点的自治性好、资源共亨的透明性强、各节点具有协同性,其主要缺点是系统状态不精确、控制机构复杂、通信开销会引起性能的下降。
分布式操作系统是网络操作系统的更高级形式,它保持了网络操作系统所拥有的全部功能,与网络操作系统的主要区别在 f 任务的分布性,即把一个大任务分解为若干个子任务,并被分派到不同的CPU上执行。
6 . 嵌入式操作系统
嵌入式操作系统运行在嵌入式智能芯片环境中,对整个智能芯片和它所操作、控制的各种部件装置等资源进行统一协调、处理、指挥和控制。
嵌入式操作系统具有微型化、可定制、实时性、可靠性、易移植性等特点。
嵌入式实时操作系统是指系统能及时响应外部事件的请求,在规定的时间内完成对该事件的处理,并控制所有实时任务协调一致地运行。嵌入式实时操作系统的特点是及时性、支持多道程序设计、高可靠性和较强的过载防护能力。
有关嵌入式实时操作系统的详细知识,将 在 17.3节中介绍。
3.1.2 操作系统的软件结构
从操作系统的结构来看,主要有整体结构、层次结构、客户/服务器结构和面向对象结构等。
1 . 整体结构
整休结构也称为模块组合结构或无序结构,是基于结构化程序设计的一种软件设计方法,其主要设计思想和步骤如下:
(1) 把模块作为操作系统的基本单位,按照功能将整个系统分解为若干个模块,每个模块具有一定的独立功能,若干个关联模块协作完成某个功能;
明确各个模块之间的接口关系,各个模块之间可以不加控制地自由调用(无序调用法);
模块之间需要传递参数或返回结果时,其个数和方式也可以根据需要随意约定。
( 2 ) 分别设计、编码、调试各个模块。
(3) 将所有模块连结成一个完整的系统。
这种结构设计方法的主要优点体现在以下三个方面:
(1) 结构紧密、组合方便,对不冋环境和用户的不同需求,可以组合不同模块来予以满足,因此,灵活性大。
(2) 针对某个功能可用最有效的算法和任意调用其他模块中的过程来实现,因此,系统效率较高。
(3) 由于划分成模块和子模块,设计及编码可齐头并进,能加快操作系统研制过程。整体式结构的主要缺点是模块独立性差,模块之间牵连甚多,形成了复杂的调用关系,甚至有很多循环调用,造成系统结构不清晰,正确性难保证,可靠性降低,系统功能的增、删、改十分困难。
2 . 层次结构
层次结构是将操作系统划分为内核和若干模块(或进程),这些模块按功能的调用次序排列成若干层次,各层之间只能是单向依赖或单向调用关系,即低层为髙层服务,高层可以调用低层的功能,反之则不能。这样,不但系统结构清晰,而且不构成循环调用。
层次结构以有全序和半序之分。
如果每层中的各模块之间保持独立,互相没有联系,则这种层次结构就称为全序;
如果某碑层内的模块之间允许有相互调用或通信的关系,则这种层次结构就称为半序。
在层次结构中,外层功能是内层功能的扩充或延伸,内层功能为外层提供了支撑和基础。因此,整个系统中的接口比其他结构方式的接口要少且简单。整个系统的正确性可通过各层的正确性来保证,从而使系统的正确性大大提高。
层次结构的另一个优点是增加、修改或替换一个层次不会影响其他层次,有利于系统的维护和扩展。然而,层次结构是分层单向依赖的,必须要建立模块间的通信机制,系统花费在通信上的开销较大,系统效率有所降低。
3 . 客户/服务器结构
现代操作系统大多拥有两种工作状态,分别是核心态和用户态。
一般应用程序: 作在用户态,而内核模块和最基本的操作系统核心工作在核心态。
客户/服务器结构也称为微内核结构。操作系统的一个发展趋势是将传统的操作系统代码放置到更高层,从操作系统中去掉尽可能多的东西,而只留下个最小的核心,称之为微内核。通常的方法是将大多数操作系统功能由在用户态运行的服务器进程来实现。为了获取某项服务,用户进程(客户进程)将请求发送给一个服务器进程,服务器进程完成此操作后,把结果返回给用户进程。这样,服务器以用户进程的形式运行,而不是运行在核心态。因此,它们不能直接访问硬件,某个服务器的崩溃不会导致整个系统的崩溃。客户/服务器结构的另一个优点是它更适用于分布式系统。
微内核技术的主要优点如下:
(1) 统一的接口,在用户态和核心态之间无需进程识别。
(2) 可伸缩性好,能适应硬件更新和应用变化。
( 3 ) 可移植性好,所有与具体机器特征相关的代码,全部隔离在微内核中,如果操作系统要移植到不冋的硬件平台上,只需修改微内核中极少代码即可。
( 4 ) 实时性好,微内核可以方便地支持实时处理。
(5) 安全可靠性高,微内核将安全性作为系统内部特性来进行设计,对外仅使用少应用编程接口。
( 6 ) 支持分布式系统,支持多处理器的体系结构和高度并行的应用程序。
4 . 面向对象结构
随着计算机的发展,面向对象技术得到了广泛的重视和应用,由于其具有数据隐藏和消息激活对象等功能,被广泛应用于操作系统的设计和实现中,特别是在网络操作系统和分布式操作系统中。
面向对象的操作系统中的对象是操作系统管理的信息和资源的抽象,可以被视为受保护的信息或资源的总称。它拥有自己的状态和存储空间,而且其状 态 (也就是存储内容)只能由事先定义好的操作来改变,而改变这些对象状态的操作又需要其他对象发送相应的消息后才能被启动,因此,容易采取某种手段对其对象实施保护。例如, Windows Server 中有执行体对象(进程、线程、文件和令牌等)和内核对象 (时钟、事件和信号等)。
3 . 2 进程管理
进程是一个具有独立功能的程序关于数据集合的一次可以并发执行的运行活动,是操作系统进行资源分配和调度的基本单位。
相对于程序,进程是动态的概念,而程序是静态的概念,是指令的集合。进程具有动态性和并发性,需要一定的资源(例如, C P U 时间、内存、文件和 I / O 设备等)来完成其任务,这些资源在创建进程或执行时被分配。在大多数操作系统中,进程是进行资源分配和调度的基本单位。
一个进程是通过其物理实体被感知的,进程的物理实体又称为进程的静态描述,通常由三部分组成,分别是程序、数据集合和进程控制块 (Process Control Block , P C B )。
- 程序描述了进程所要完成的功能和逻辑运算
- 数据集合描述了程序运行所需要的数据部分和工作区,
- P C B 包括进程的描述信息、控制信息和资源信息,是进程动态特性的集中反映。是操作系统管理进程的方式。
程序和数据集合是进程存在的物质基础,是进程的实体;
P C B 是进程存在的标志,进程与 P C B是一对一的关系,操作系统利用 P C B 对并发执行的进程进行控制和管理。
3.2.1进程的状态(单进程状态)
一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时
虽可运行但分不到处理器,有时虽有空闲处理但因等待某个事件的发生而无法执行,
这一切都说明进程和程序不相同,它是活动的且有状态变化的。
1 . 三态模型
进程具有三种最基本的状态,分别是运行、就绪和阻塞,如图3-1所示。
(1) 运行状态:正在使用CPU资源
运行状态是进程占用处理机正在执行其程序的状态。
在单处理机CPU系统中,某个时刻只能有一个进程处于运行状态;
在多处理机系统中,可能有多个进程同时处于运行状态。
(2) 阻塞状态:等待IO资源
阻塞状态也称为等待状态或睡眠状态,是进程由于等待某个事件的发生而处于暂停执行的状态。
例如,进程因等待 I / O 的完成或等待缓冲空间等。
(3) 就绪状态:等待CPU资源
就绪状态是进程已分配到除处理机以外的所有必要资源,具备了执行的条件,等待处理机调度的状态。
在系统中,同一时刻可能会有多个进程处于就绪状态,排成就绪队列。
2 . 五态模型
由于新进程的不断创建,系统资源特别是内存资源已不能满足所有进程运行的要求(或是创建的进程太多或是物理内存太小,都可能出现内存资源不足的情形)
这时就必须将某些进程挂起,放到磁盘对换区(SWAP分区),暂时不参加调度,以均衡负载。
进程挂起的原因可能是系统出现故障,或者是用户调试程序,也可能是需要检查问题。
图3-2是具有挂起状态的进程状态及其转换。
活跃就绪是指进程在内存并且可被调度的状态。
静止就绪是指进程被对换到外存时的就绪状态,是不能被直接调度的状态,只有当内存中没有活跃就绪态进程,或者挂起就绪态进程具有更高的优先级,系统才能把挂起就绪态进程调回内存,并转换为活跃就绪。
这种情况,只有就绪进程的数量巨大时,才会出现,只有进程的数量少,进程的PCB不会被调入到外存中的。
活跃阻塞状态是指进程已在内存,一旦所等待的事件发生,便进入活跃就绪状态:
静止阻塞状态是指进程对换到外存时的阻塞状态,一旦所等待的事件发生,便进入静止
就绪状态。
这种情况,只有就绪进程的数量巨大时,才会出现,只有进程的数量少,进程的PCB不会被调入到外存中的。
3 . 2 . 2 信号量与P V 操作(进程间合作)
在多道程序系统中,由于资源共享与进程合作,使各进程之间可能产生两种形式的制约关系,
一种是间接相互制约,例如,在仅有一台打印机的系统中,有两个进程A 和B , 如果进程A 需要打印时,系统已将打印机分配给进程B , 则进程A 必须阻塞;一旦 进程B 将打印机释放,系统便将进程A 唤醒,使之由阻塞状态变为就绪状态;
另一种是直接相互制约,例如,输入进程A 通过单缓冲K向进程B 提供数据。当该缓冲区为空时, 进 程 B 不能获得所需的数据而阻塞,一旦进程A 将数据送入缓冲区中,进 程 B 就被唤 醒。反之,当缓冲区满时,进程A 就被阻塞,仅当进程B 取走缓冲区中的数据时,才唤 醒进程A 。
进程同步主要源于进程合作,是进程之间共同完成一项任务时直接发生相互作用的关系,为进程之间的直接制约关系。在多道程序系统中,这种进程间在执行次序上的调用是必不可少的;
进程互斥主要源于资源共享,是进程之间的间接制约关系。在多道程 序系统中,每次只允许一个进程访问的资源称为临界资源,进程互斥要求保证每次只有 一个进程使用临界资源。在每个进程中访问临界资源的程序段称为临界区,进程进入临 界区要满足一定的条件,以保证临界资源的安全使用和系统的正常运行。
3. 2. 3 死锁问题
当若十个进程竞争使用资源时,如果每个进程都占有了一定的资源,又申请使用已被另一个进程占用、且不能抢占的资源,则所有这些进程都纷纷进入阻塞状态,不能继续运行,即系统中两个或两个以上的进程无限期地等待永远不会发生的条件,系统处于一种停滞状态,这种现象就称为死锁。产生死锁的主要原因是,系统缺少足够的资源供进程使用,对互斥资源的共享与并发执行的顺序不当,以及资源分配不当。产生死锁的4 个必要条件如下:
(1) 互斥条件。任一时刻只允许一个进程使用资源。 //所任共享资源,如果独自,就不存在死锁
(2) 不剥夺条件。进程已经占用的资源,不会被强制剥夺。//以申请的资源不能被抢占,才会出现死锁,如果有一个进程横强势,可以抢占任何人的资源,就这个人就不存在死锁的情形。
(3) 请求与保持条件。进程在请求其余资源时,不主动释放已经占有的资源。//进程没有获得其他资源前,不会主动释放资源,如果进程比较谦让,主动给其他进程让出资源,也不会出现死锁。
(4) 环路条件。环路中每一条边是进程在请求另一个进程己经占有的资源。//所相互等待对方资源的情形,如果不等待对方资源,就不会出现永远获取不了锁的情形 。
对死锁的处理,常用的方法有死锁的预防、避免和检测与解除等方法,它们各自的性能和主要优缺点如表3-4所示。
打破死锁的手段,就是打破死锁形成的4个条件中的任意一个条件:
1 . 死锁预防:在死锁没有发生前就采取手段,避免进程满足上述4个条件
所谓死锁预防,就是采用某种策略,限制并发进程对资源的请求,使系统在任何时刻都不满足死锁的必要条件。
死锁预防主要是针对破坏死锁的4 个必要条件进行的。
(1) 破坏互斥条件 =》 共享是不可避免,此条件不存在
由于这是设备的固有特性,很难改变,因此不仅不能改变,还应设法加以保证。
(2) 破坏不剥夺条件 =》 主动让出资源:不满足条件后,暂时释放所有资源。
如果进程申请新的资源而得不到满足,则暂时释放已有的资源。这种策略实现复杂,例如,要保护进程及资源释放的现场等。此外,该策略还可能由于反复地中请和释放资源,使进程的执行无限推迟,延长了进程的周转时间,增加了系统开销,降低了系统吞吐量。
(3) 破坏请求与保持条件 =》 把所有的资源一次性打包,就不存在等待部分资源的情形。
进程一次性申请全部资源,系统若有足够资源,则一次性把其所需资源分配给进程。在分配时,只有一个资源要求不能满足,则已有的其他资源也全部不分配给该进程,该进程只能等待。由于等待期间,该进程未占有任何资源,因此可以避免死锁。
该策略的优点是简单、易于实现,但也可能造成资源浪费,以及进程延迟运行。
(4) 破坏环路条件 =》避免相互死等,打破环路等待。
这种策略将资源进行编号,进程按照资源的编号进行有序申请。
该策略的主要缺点是,为系统中各种资源分配的序号必须相对稳定,尽管在分配资源序号时,考虑了大多数进程实际使用这些资源的排序,但也会经常发生进程使用资源的顺序与系统规定的顺序不同的情况,造成资源的浪费。另外,按规定次序申请资源的方法,限制了用户简单、自由地编程。
2 . 死锁避免 (最常见高效的做法)
死锁避免是将限制条件弱化,允许死锁的存在,但不让它发生,设置一种安全状态,进程按照某种顺序来为其分配资源。在某一时刻,系统能按某种顺序为每个进程分配其所需资源,直到最大需求,使每个进程都能顺利地完成(每次分配资源后,确保剩下的资源,能够让拥有资源的线程不会陷入死锁,确保剩下的资源能够安全,如果剩下的资源会导致资源不足,出现死锁,则该资源就不能分配给新的进程),则称此时系统处安全状态。反之,称之为不安全状态。例如,在系统资源分配状态如表3-5所示时,系统处于安全状态。因为此时存在一个安全序列<P2, P I , P 3>。
上述方法:必须确保所有进程都不会出现死锁,而不是一个线程不出现死锁。
3 . 死锁检测和解除
死锁检测是指系统保存资源的请求和分配信息,利用某种算法对这些信息加以检査,以判断是否存在死锁。死锁检测算法主要检査是否有循环等待,可以对资源分配图进行简化來检测是否处于死锁状态,如图3-3所示。在图3-3中,有向图的顶点为资源或进程,从资源 R 1 指向进程 P 1 的边表示 R 1 已分配给 P 1,从进程 P 1 指向资源 R 2 的边表示 P 1 正因请求 R 2 而处于等待状态。有向图
中的回路表示可能存在死锁。
(1)既然死了,不如释放资源给其他人用
(2)一个大象,救火一群蚂蚁
(3)发扬雷锋精神
3. 2. 4 线程管理
在现代操作系统中,通常都引进了线程的概念。
线程是进程的活动成分,是处理器分配资源的最小单位,它可以共享进程的资源与地址空间,通过线程的活动,进程可以提供多种服务(对系统进程而言)或实行子任务并行(对用户进程而言)。每个进程创建时只有一个线程,根据需要在运行过程中创建更多的线程(前者也可称“主线程”)。显然,只有主线程的进程才是传统意义下的进程。
1 . 线程的实现方式
线程基本上不拥有系统资源,只拥有在运行中必不可少的资源,例如,线程状态、寄存器上下文和栈等,它可与同属一个进程的其他线程共享进程所拥有的全部资源(内存、地址空间、IO设备)。线程也有就绪、阻塞和执行等基本状态,一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。由线程之间的相互制约,致使线程在运行中也呈现出间断性。
线程实现方式主要有以下三种:
备注:整个内核是一个超级进程!!!内核内的所有线程共享整个内核进程的资源!!!
(1) 内核线程 =》一个用户线程对应一个内核线程
内核线程依赖子操作系统内核,由内核的内部需求进行创建和撤销。
一个线程发起系统调用而阻塞,不会影响其他线程。系统将 C P U 时间片分配给各线程,所以,多线程的进程可以获得更多的 C P U 时间。
(2) 用户线程 =》 进程的所有线程,共享一个内核线程,内核线程并不知道有多个用户线程。
用户线程不依赖于操作系统内核,进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。调度由应用软件内部进行,通常采用非抢先式或更简单的规则,无需在用户态和核心态之间切换,因此,速度特别快。
如果某个线程因系统调用而阻塞,则整个进程需要等待。系统将 C P U 时间片分配给进程,所以,多线
程时每个线程就慢。
(3) 轻权进程 =》用户线程看成一个轻量级的进程,每个轻量级的进程,对应一个内核线程。
轻权进程是操作系统内核支持的用户线程 。
一 个进程可有一个或多个轻权进程,每个轻权进程由一个单独的内核线程来支持。
2 . 与进程的比较
在引入线程的操作系统中,通常一个进程有若干个线程,至少也需要有一个线程。
进程和线程的区别主要体现在以下5 个方面:
(1) 调度。
在传统的操作系统中,拥有资源的基本单位和独立调度、分配的基本单位都是进程。而在引入线程的操作系统中,则将线程作为调度和分配的基本单位,将进程作为资源拥有的基本单位。‘
(2) 并发性。
在引入线程的操作系统中,不仅进程之间可以并发执行,而且同一个进程的多个线程之间也可并发执行,从而使操作系统具有更好的并发性,能够有效地使用多个资源和提高系统吞吐量。
(3) 拥有资源 。
一 般来说,线程除了拥有一点必不可少的资源外,它自己不拥有系统资源,但它可以访问其隶属进程的资源。也就是说,一个进程所拥有的资源可供它的所有线程共享。
(4) 系统开销。
在进程切换时,涉及整个当前进程 C P U 环境的保存和新被调度运行进程的 C P U 环境的设置、裸机地址空间的切换•,而线程切换只需保存和设置少量寄存器的内容,并不涉及存储器管理方面的操作。由此吋见,进程切换的开销远大于线程切换的开销。此外,由于同一进程中的多个线程具有相同的地址空间,这使它们之间的同步和通信变得比较容易。在有的系统中,线程的切换、同步和通信都无需操作系统内核的干预。
(5) 通信方面。
进程间通信需要进程同步和互斥手段的辅助,以保证数据一致性,而线程间可以直接读写进程数据段(例如,全局变量等)来进行通信。
3 . 多线程模型
许多操作系统都提供用户和内核线程支持 , 从而有不同的多线程模型。
(1) 多对一模型。
多对一模型将多个用户线程映射到一个内核线程,如图3-4所示。线程管理是在用户空间进行的,因此效率比较髙。但是,如果一个线程执行了阻塞系统调用(通过内核访问共享资源),那么整个进程就会阻塞,(之所以阻塞,这是因为多个用户空间线程共享同一个内核线程,阻塞在同调用上,本质是内核线程阻塞了,因此所有的用户线性都被阻塞,即整个进程被阻塞)。而且,因为任一时刻进程中只有一个线程能够访问内核,多个线程不能并行运行在多处理器上。
这种方法,就是一个用户进程对应一个内核线程,即一个用户进程的所有线程都共享一个进程对应的内核线程!这种方案对不需要内核的专门支持,只需要在用户空间对多个线程进行管理即可。
在内核看来,多个用户线程还是一个线程。
(2)一对一模型
(3)多对多模型
3. 2. 4 线程控制块PCB
(1)系统进程控制块
进程控制块(Processing Control Block),是操作系统核心中一种数据结构,主要表示进程状态。其作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位或与其它进程并发执行的进程。或者说,OS是根据PCB来对并发执行的进程进行控制和管理的。
PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息,它使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位或一个能与其他进程并发执行的进程。
-
程序计数器:接着要运行的指令地址。
-
进程状态:可以是new、ready、running、waiting或 blocked等。
-
CPU暂存器:如累加器、索引暂存器(Index register)、堆栈指针以及一般用途暂存器、状况代码等,主要用途在于中断时暂时存储数据,以便稍后继续利用;其数量及类因电脑架构有所差异。
-
CPU排班法:优先级、排班队列等指针以及其他参数。
-
存储器管理:如标签页表等。
-
会计信息:如CPU与实际时间之使用数量、时限、账号、工作或进程号码。
-
输入输出状态:配置进程使用I/O设备,如磁带机。
(2)进程独自进程控制块
进程状态(State)
进程执行时,它会根据具体情况改变状态。进程状态是调度和对换的依据。Linux 中的 进程主要有如下状态,如表4.1 所示。
可运行状态:处于这种状态的进程,要么正在运行、要么正准备运行。正在运行的进程就是当前进程 (由 current 宏 所指向的进程),而准备运行的进程只要得到CPU 就可以立即投入运行,CPU 是 这些进程唯一等待的系统资源。系统中有一个运行队列(run_queue),用来容纳所有处于可 运行状态的进程,调度程序执行时,从中选择一个进程投入运行。 当前运行进程一直处于该队列中,也就是说,current 总是指向运行队列中的某个元素,只是具体指向谁由调度程序决定。
等待状态:处于该状态的进程正在等待某个事件(Event)或某个资源,它肯定位于系统中的某个 等待队列(wait_queue)中。Linux 中处于等待状态的进程分为两种:可中断的等待状态和 不可中断的等待状态。处于可中断等待态的进程可以被信号唤醒,如果收到信号,该进程就 从等待状态进入可运行状态,并且加入到运行队列中,等待被调度;而处于不可中断等待态 的进程是因为硬件环境不能满足而等待,例如等待特定的系统资源,它任何情况下都不能被 打断,只能用特定的方式来唤醒它,例如唤醒函数wake_up()等。
暂停状态:此时的进程暂时停止运行来接受某种特殊处理。通常当进程接收到SIGSTOP、SIGTSTP、 SIGTTIN 或 SIGTTOU 信号后就处于这种状态。例如,正接受调试的进程就处于这种状态。
僵死状态:进程虽然已经终止,但由于某种原因,父进程还没有执行wait()系统调用,终止进程的 信息也还没有回收。顾名思义,处于该状态的进程就是死进程,这种进程实际上是系统中的 垃圾,必须进行相应处理以释放其占用的资源。
进程调度信息
调度程序利用这部分信息决定系统中哪个进程最应该运行,并结合进程的状态信息保证 系统运转的公平和高效。这一部分信息通常包括进程的类别(普通进程还是实时进程)、进 程的优先级等,如表4.2 所示。
当need_resched 被设置时,在“下一次的调度机 会”就调用调度程序schedule();counter 代表进程剩余的时间片,是进程调度的主要依据, 也可以说是进程的动态优先级,因为这个值在不断地减少;nice 是进程的静态优先级,同时 也代表进程的时间片,用于对counter 赋值,可以用nice()系统调用改变这个值;policy 是适用于该进程的调度策略,实时进程和普通进程的调度策略是不同的;rt_priority 只对 实时进程有意义,它是实时进程调度的依据。
进程的调度策略有3 种,如表4.3 所示。
只有root 用户能通过sched_setscheduler()系统调用来改变调度策略。
标识符(Identifiers)
每个进程有进程标识符、用户标识符、组标识符,如表4.4 所示。 不管对内核还是普通用户来说,怎么用一种简单的方式识别不同的进程呢?这就引入了 进程标识符( PID,process identifier ),每个进程都有一个唯一的标识符,内核通过这个 标识符来识别不同的进程,同时,进程标识符PID 也是内核提供给用户程序的接口,用户程 序通过PID 对进程发号施令。PID 是32 位的无符号整数,它被顺序编号:新创建进程的PID 通常是前一个进程的PID 加1。然而,为了与16 位硬件平台的传统Linux 系统保持兼容,在 Linux 上允许的最大PID 号是32767,当内核在系统中创建第32768 个进程时,就必须重新开 始使用已闲置的PID 号。
进程通信有关信息(IPC,Inter_Process Communication)
为了使进程能在同一项任务上协调工作,进程之间必须能进行通信即交流数据。 Linux 支持多种不同形式的通信机制。它支持典型的UNIX 通信机制(IPC Mechanisms): 信号(Signals)、管道(Pipes),也支持System V / Posix 通信机制:共享内存(Shared Memory)、 信号量和消息队列(Message Queues),如表4.5 所示。
进程链接信息(Links)
程序创建的进程具有父/子关系。因为一个进程能创建几个子进程,而子进程之间有兄 弟关系,在task_struct 结构中有几个域来表示这种关系。 在Linux 系统中,除了初始化进程init,其他进程都有一个父进程(Parent Process) 。可以通过fork()或clone()系统调用来创建子进程,除了进程标识符(PID) 等必要的信息外,子进程的task_struct 结构中的绝大部分的信息都是从父进程中拷贝 。系统有必要记录这种“亲属”关系,使进程之间的协作更加方便,例如 父进程给子进程发送杀死(kill)信号、父子进程通信等。 每个进程的task_struct 结构有许多指针,通过这些指针,系统中所有进程的 task_struct结构就构成了一棵进程树,这棵进程树的根就是初始化进程init的task_struct 结构(init 进程是Linux 内核建立起来后人为创建的一个进程,是所有进程的祖先进程)。表4.6 是进程所有的链接信息。
时间和定时器信息(Times and Timers)
一个进程从创建到终止叫做该进程的生存期(lifetime)。进程在其生存期内使用CPU 的时间,内核都要进行记录,以便进行统计、计费等有关操作。进程耗费CPU 的时间由两部 分组成:一是在用户模式(或称为用户态)下耗费的时间、一是在系统模式(或称为系统态) 下耗费的时间。每个时钟滴答,也就是每个时钟中断,内核都要更新当前进程耗费CPU 的时 间信息。
文件系统信息(File System)
进程可以打开或关闭文件,文件属于系统资源,Linux 内核要对进程使用文件的情况进 行记录。task_struct 结构中有两个数据结构用于描述进程与文件相关的信息。其中, fs_struct 中描述了两个VFS 索引节点(VFS inode),这两个索引节点叫做root 和pwd,分 别指向进程的可执行映像所对应的根目录(Home Directory)和当前目录或工作目录。 file_struct 结构用来记录了进程打开的文件的描述符(Descriptor)。如表4.9 所示。
在文件系统中,每个VFS 索引节点唯一描述一个文件或目录,同时该节点也是向更低层 的文件系统提供的统一的接口。
虚拟内存信息(Virtual Memory)
除了内核线程(Kernel Thread),每个用户进程都拥有自己的地址空间(也叫虚拟空间), 用 mm_struct 来描述。另外Linux 2.4 还引入了另外一个域active_mm,这是为内核线程而 引入的。因为内核线程没有自己的地址空间,为了让内核线程与普通进程具有统一的上下文 切换方式,当内核线程进行上下文切换时,让切换进来的线程的active_mm 指向刚被调度出 去的进程的mm_struct。内存 信息如表4.10 所示。
页面管理信息
页表内页面的换入换出需要页面管理信息,有关页面的描述信息如表4.11。
对称多处理机(SMP)信息
Linux 2.4 对SMP 进行了全面的支持,表4.12 是与多处理机相关的几个域。
和处理器相关的环境(上下文)信息(Processor Specific Context)
这里要特别注意标题:和“处理器”相关的环境信息。进程作为一个执行环境的综合, 当系统调度某个进程执行,即为该进程建立完整的环境时,处理器(Processor)的寄存器、 堆栈等是必不可少的。因为不同的处理器对内部寄存器和堆栈的定义不尽相同,所以叫做“和 处理器相关的环境”,也叫做“处理机状态”。当进程暂时停止运行时,处理机状态必须保 存在进程的 thread_struct 结构中,当进程被调度重新运行时再从中恢复这些环境,也就是恢 复这些寄存器和堆栈的值。处理机信息如表4.13 所示。
其他成员
- struct wait_queue *wait_chldexit :在进程结束时,或发出系统调用wait 时,为了等待子进程的结束,而将自己(父进程)睡眠在该等待队列上,设置状态标志为TASK_INTERRUPTIBLE,并且把控制权转给调度程序。
- struct rlimit rlim[RLIM_NLIMITS] :每一个进程可以通过系统调用setrlimit 和getrlimit来限制它资源的使用。
- int exit_code exit_signal :程序的返回代码以及程序异常终止产生的信号,这些数据由父进程(子进程完成后)轮流查询。
- char comm[16] :这个域存储进程执行的程序的名字,这个名字用在调试中。
- Unsigned long personality :Linux 可以运行X86 平台上其他UNIX 操作系统生成的符合iBCS2标准的程序, personality 进一步描述进程执行的程序属于何种UNIX 平台的“个性”信息。通常有PER_Linux,PER_Linux_32BIT,PER_Linux_EM86,PER_SVR4,PER_SVR3,PER_SCOSVR3, PER_WYSEV 386,PER_ISCR4,PER_BSD,PER_XENIX 和PER_MASK等,参见include/Linux/personality.h>。
- int did_exec:1 :按POSIX 要求设计的布尔量,区分进程正在执行老程序代码,还是用系统调用execve()装入一个新的程序。
- struct linux_binfmt *binfmt :指向进程所属的全局执行文件格式结构,共有a.out、script、elf、java 等4 种。