操作系统学习-进程管理

来源:互联网 发布:中国宠物人口数据分析 编辑:程序博客网 时间:2024/04/28 12:34

作者:YouChuang

本文主要是最近重新学习《计算机操作系统》教材时的一些笔记和思考:进程管理


  • 进程基本概念
    • 进程由来
    • 进程状态
  • 进程控制
    • 创建进程
    • 进程终止
    • 进程阻塞和唤醒
    • 进程挂起和激活
  • 进程同步
    • 基本概念
    • 信号量机制
  • 经典进程同步问题
    • 生产者消费者问题
    • 哲 学 家 进 餐 问题
    • 读 者 写者问题
  • 进程通信
    • 共享存储器系统
    • 消息传递系统
    • 管道通信系统
  • 页面置换算法
    • Clock置换算法
    • 改进型Clock置换算法


进程基本概念

进程由来

  • 程序顺序执行时的特征
    顺序封闭可再现

  • 程序并发执行时的特征
    共享资源
    间断性,会出现暂停
    失去封闭性
    不可再现性

为使程序能并发执行,且为了对并发执行的程序加以描述和控制,人们引入了“进程”的概念。

  • 进程控制块
    为使程序(含数据)能独立运行,应为之配置一进程控制块,即PCB(Process Control Block);而由程序段、相关的数据段和PCB三部分便构成了进程实体。

  • 进程与程序
    进程的实质是进程实体的一次执行过程,因此,动态性是进程的最基本的特征。动态性还表现在:“它由创建而产生,由调度而执行,由撤消而消亡”。可见,进程实体有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有运动的含义,因而是静态的。

进程状态

  • 就绪状态
    当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态,进程已获得CPU,其程序正在执行。

  • 阻塞状态
    正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。

  • 挂起状态
    引入挂起状态的原因有:
    (1) 终端用户的请求。当终端用户在自己的程序运行期间发现有可疑问题时,希望暂时使自己的程序静止下来。亦即,使正在执行的进程暂停执行;若此时用户进程正处于就绪状态而未执行,则该进程暂不接受调度,以便用户研究其执行情况或对程序进行修改。我们把这种静止状态称为挂起状态。
    (2) 父进程请求。有时父进程希望挂起自己的某个子进程,以便考查和修改该子进程,或者协调各子进程间的活动。
    (3) 负荷调节的需要。当实时系统中的工作负荷较重,已可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起,以保证系统能正常运行。
    (4) 操作系统的需要。操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账

带有挂起状态的进程状态转换图

  • 引入创建状态,是为了保证进程的调度必须在创建工作完成后进行,以确保对进程控制块操作的完整性。同时,创建状态的引入,也增加了管理的灵活性,操作系统可以根据系统性能或主存容量的限制,推迟创建状态进程的提交。对于处于创建状态的进程,获得了其所必需的资源,以及对其PCB初始化工作完成后,进程状态便可由创建状态转入就绪

进程的五种基本状态及转换

  • 创建→活动就绪:在当前系统的性能和内存的容量均允许的情况下,完成对进程创建的必要操作后,相应的系统进程将进程的状态转换为活动就绪状态

  • 创建→静止就绪:考虑到系统当前资源状况和性能要求,并不分配给新建进程所需资源,主要是主存资源,相应的系统进程将进程状态转为静止就绪状态,对换到外存,不再参与调度,此时进程创建工作尚未完成。

具有创建、终止和挂起状态的进程状态图

  • 进程控制块的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。或者说,OS是根据PCB来对并发执行的进程进行控制和管理的
    PCB是进程存在的惟一标志。
    因为PCB经常被系统访问,尤其是被运行频率很高的进程及分派程序访问,故PCB应常驻内存。系统将所有的PCB组织成若干个链表(或队列),存放在操作系统中专门开辟的 PCB 区内。例如在 Linux 系统中用task_struct数据结构来描述每个进程的进程控制块,在 Windows操作系统中则使用一个执行体进程块(EPROCESS)来表示进程对象的基本属性。

  • 进程标识符 进程标识符用于惟一地标识一个进程。
    一个进程通常有两种标识符:
    内部标识符。在所有的操作系统中,都为每一个进程赋予了一个惟一的数字标识符,它通常是一个进程的序号。设置内部标识符主要是为了方便系统使用。
    外部标识符。

  • 处理机状态信息主要是由处理机的各种寄存器中的内容组成的。处理机在运行时,许多信息都放在寄存器中。当处理机被中断时,所有这些信息都必须保存在 PCB中,以便在该进程重新执行时,能从断点继续执行。
    寄存器包括:
    ① 通用寄存器,又称为用户可视寄存器,它们是用户程序可以访问的,用于暂存信息,在大多数处理机中,有 8~32 个通用寄存器,在 RISC 结构的计算机中可超过 100 个;
    ② 指令计数器,其中存放了要访问的下一条指令的地址;
    ③ 程序状态字PSW,其中含有状态信息,如条件码、执行方式、中断屏蔽标志等;
    ④ 用户栈指针,指每个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用参数及调用地址,栈指针指向该栈的栈顶。

  • 进程调度信息在PCB中还存放一些与进程调度和进程对换有关的信息,包括:
    ① 进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
    ② 进程优先级,用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机;
    ③ 进程调度所需的其它信息,它们与所采用的进程调度算法有关,比如,进程已等待CPU的时间总和、进程已执行的时间总和等;
    ④ 事件,指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。

  • 进程控制信息包括:
    ① 程序和数据的地址,指进程的程序和数据所在的内存或外存地(首)址,以便再调度到该进程执行时,能从PCB中找到其程序和数据;
    ② 进程同步和通信机制,指实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在PCB中;
    ③ 资源清单,即一张列出了除CPU以外的、进程所需的全部资源及已经分配到该进程的资源的清单;
    ④ 链接指针,它给出了本进程(PCB)所在队列中的下一个进程的PCB的首地址。

进程控制

  • 进程控制一般是由OS的内核中的原语来实现的。 原语(Primitive)是由若干条指令组成的,用于完成一定功能的一个过程。它与一般过程的区别在于:它们是“原子操作(Action Operation)”。所谓原子操作,是指一个操作中的所有动作要么全做,要么全不做。换言之,它是一个不可分割的基本单位,因此,在执行过程中不允许被中断。原子操作在管态下执行,常驻内存。

  • 引起创建进程的事件 在多道程序环境中,只有(作为)进程(时)才能在系统中运行
    用户登录。在分时系统中,用户在终端键入登录命令后,如果是合法用户,系统将为该终端建立一个进程,并把它插入就绪队列中。
    作业调度。在批处理系统中,当作业调度程序按一定的算法调度到某作业时,便将该作业装入内存,为它分配必要的资源,并立即为它创建进程,再插入就绪队列中。
    提供服务。当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务,例如,用户程序要求进行文件打印,操作系统将为它创建一个打印进程,这样,不仅可使打印进程与该用户进程并发执行,而且还便于计算出为完成打印任务所花费的时间。
    应用请求。在上述三种情况下,都是由系统内核为它创建一个新进程;而第4类事件则是基于应用进程的需求,由它自己创建一个新进程,以便使新进程以并发运行方式完成特定任务。例如,某应用程序需要不断地从键盘终端输入数据,继而又要对输入数据进行相应的处理,然后,再将处理结果以表格形式在屏幕上显示。该应用进程为使这几个操作能并发执行,以加速任务的完成,可以分别建立键盘输入进程、表格输出进程。

创建进程

  • 申请空白PCB
  • 为新进程分配资源
  • 初始化进程控制块
  • 将新进程插入就绪队列,如果进程就绪队列能够接纳新进程,便将新进程插入就绪队

进程终止

  • 引起进程终止的事件
    异常结束
    越界错误
    保护错
    非法指令
    外界干预
    操作员或操作系统干预
    父进程请求
    父进程终止

进程阻塞和唤醒

  • 引起进程阻塞和唤醒的事件
    请求系统服务。当正在执行的进程请求操作系统提供服务时,由于某种原因,操作系统并不立即满足该进程的要求时,该进程只能转变为阻塞状态来等待启动某种操作。当进程启动某种操作后,如果该进程必须在该操作完成之后才能继续执行,则必须先使该进程阻塞,以等待该操作完成新数据尚未到达。对于相互合作的进程,如果其中一个进程需要先获得另一(合作)进程提供的数据后才能对数据进行处理,则只要其所需数据尚未到达,该进程只有(等待)阻塞,无新工作可做。系统往往设置一些具有某特定功能的系统进程,每当这种进程完成任务后,便把自己阻塞起来以等待新任务到来。
  • 进程阻塞过程
    正在执行的进程,当发现上述某事件时,由于无法继续执行,于是进程便通过调用阻塞原语block把自己阻塞。可见,进程的阻塞是进程自身的一种主动行为。
    当被阻塞进程所期待的事件出现时,如I/O完成或其所期待的数据已经到达,则由有关进程(比如用完并释放了该I/O设备的进程)调用唤醒原语wakeup( ),将等待该事件的进程唤醒。
    应当指出,block 原语和 wakeup 原语是一对作用刚好相反的原语。因此,如果在某进程中调用了阻塞原语,则必须在与之相合作的另一进程中或其他相关的进程中安排唤醒原语,以能唤醒阻塞进程;否则,被阻塞进程将会因不能被唤醒而长久地处于阻塞状态,从而再无机会继续运行。

进程挂起和激活

系统将利用激活原语active( )将指定进程激活。激活原语先将进程从外存调入内存,检查该进程的现行状态。

进程同步

基本概念

  • 制约关系
    间接相互制约关系。同处于一个系统中的进程,通常都共享着某种系统资源,如共享 CPU、共享 I/O 设备等。所谓间接相互制约即源于这种资源共享
    直接相互制约关系。这种制约主要源于进程间的合作
    生产者-消费者(producer-consumer)问题是一个著名的进程同步问题

  • 临界资源
    程序的执行失去了再现性。为了预防产生这种错误,解决此问题的关键是应把变量counter作为临界资源处理,亦即,令生产者进程和消费者进程互斥地访问变量counter。

  • 临界区
    人们把在每个进程中访问临界资源的那段代码称为临界区(critical section)。显然 ,若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。为此,每个进程在进入临界区之前,应先对欲访问的临界资源进行检查,看它是否正被访问

  • 进入区和退出区
    必须在临界区前面增加一段用于进行上述检查的代码,把这段代码称为进入区(entry section)。相应地,在临界区后面也要加上一段称为退出区(exit section)的代码,用于将临界区正被访问的标志恢复为未被访问的标志。

  • 所有同步机制都应遵循下述四条准则:
    (1) 空闲让进。当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。
    (2) 忙则等待。当已有进程进入临界区时,表明临界资源正在被访问,因而其它试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。
    (3) 有限等待。对要求访问临界资源的进程,应 保证在有限时间内能进入自己的临界区,以免陷入“死等”状态。
    (4) 让权等待。当进程不能进入自己的临界区时,应 立 即 释 放 处理机,以 免 进程陷入“忙等”状态。

信号量机制

1965年,荷兰学者Dijkstra提出的信号量(Semaphores)机制是一种卓有成效的进程同步工具。

最初由Dijkstra把整型信号量定义为一个用于表示资源数目的整型量S,它与一般整型量不同,除初始化外,仅能通过两个标准的原子操作(Atomic Operation) wait(S)和signal(S)来访问。很长时间以来,这两个操作一直被分别称为P、V操作。

wait(S):     while S<=0 do no-op;    S:=S-1; signal(S):    S:=S+1; 

wait(S)和signal(S)是两个原子操作,因此,它们在执行时是不可中断的。

  • 存在的问题
    整型信号量机制中的wait操作,只要是信号量S≤0,就会不断地测试。因此,该机制并未遵循“让权等待”的准则,而是使进程处于“忙等”的状态。
    在采取了“让权等待”的策略后,又会出现多个进程等待访问同一临界资源的情况。
    为此,在信号量机制中,除了需要一个用于代表资源数目的整型变量value外,还应增加一个进程链表指针L,用于链接上述的所有等待进程。
    记录型信号量是由于它采用了记录型的数据结构而得名;当 S.value<0时,表示该类资源已分配完毕,因此进程应调用block原语,进行自我阻塞,放弃处理机,并插入到信号量链表S.L 中。
    可见,该机制遵循了“让权等待”准则。此时 S.value 的绝对值表示在该信号量链表中已阻塞进程的数目
    若加1后仍是S.value≤0,则表示在该信号量链表中,仍有等待该资源的进程被阻塞,故还应调用wakeup原语,将S.L链表中的第一个等待进程唤醒
    注意边界条件,小于等于0,意思就是只要之前有等待的进程,加一后可以满足一个等待进程的资源请求,所以就唤醒一个等待进程。
    如果S.value的初值为1,表示只允许一个进程访问临界资源,此时的信号量转化为互斥信号量,用于进程互斥。

  • 新的问题
    在有些应用场合,是一个进程需要先获得两个或更多的共享资源后方能执行其任务。

  • AND同步机制的基本思想
    将进程在整个运行过程中需要的所有资源,一次性全部地分配给进程,待进程使用完后再一起释放。只要尚有一个资源未能分配给进程,其它所有可能为之分配的资源也不分配给它。亦即,对若干个临界资源的分配,采取原子操作方式:要么把它所请求的资源全部分配到进程,要么一个也不分配。由死锁理论可知,这样就可避免上述死锁情况的发生。为此,在 wait操作中,增加了一个“AND”条件,故称为AND同步,或称为同时wait操作
    只是wait,没有说signal

  • 进一步
    在记录型信号量机制中,wait(S)或signal(S)操作仅能对信号量施以加1或减1操作,意味着每次只能获得或释放一个单位的临界资源。而当一次需要 N 个某类临界资源时,便要进行N次wait(S)操作,显然这是低效的。此外,在有些情况下,当资源数量低于某一下限值时,便不予以分配。因而,在每次分配之前,都必须测试该资源的数量,看其是否大于其下限值。基于上述两点,可以对AND信号量机制加以扩充,形成一般化的“信号量集”机制。
    一次分配多个资源,且考虑资源下限

  • 信号量集的表示
    (1) Swait(S,d,d)。此时在信号量集中只有一个信号量 S,但允许它每次申请 d 个资源,当现有资源数少于d时,不予分配。
    (2) Swait(S,1,1)。此时的信号量集已蜕化为一般的记录型信号量(S>1时)或互斥信号量(S=1时)。
    (3) Swait(S,1,0)。这是一种很特殊且很有用的信号量操作。当 S≥1 时,允许多个进程进入某特定区;当 S 变为 0 后,将阻止任何进程进入特定区。换言之,它相当于一个可控开关。

  • 信号量的应用
    1.利用信号量实现进程互斥
    2.利用信号量实现前趋关系

  • 管程机制
    实际应用情况如何?
    代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成了一个操作系统的资源管理模块,我们称之为管程

  • 管程由四部分组成
    ① 管程的名称;
    ② 局部于管程内部的共享数据结构说明;
    ③ 对该数据结构进行操作的一组过程;
    ④ 对局部于管程内部的共享数据设置初始值的语句

经典进程同步问题

“生产者—消费者”问题

  • 利用记录型信号量解决生产者—消费者问题
    首先,在每个程序中用于实现互斥的 wait(mutex)和signal(mutex)必须成对地出现;
    其次,对资源信号量empty和full的wait和signal操作,同样需要成对地出现,但它们分别处于不同的程序中
    最后,在每个程序中的多个 wait 操作顺序不能颠倒,应先执行对资源信号量的wait操作,然后再执行对互斥信号量的wait操作,否则可能引起进程死锁。
    对于生产者—消费者问题,也可利用 AND 信号量来解决,即用 Swait(empty,mutex)来代替wait(empty)和wait(mutex);

“ 哲 学 家 进 餐 问题”

由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题

当哲学家饥饿时,总是先去拿他左边的筷子,即执行wait(chopstick[i]); 成功后,再去拿他右边的筷子,即执行wait(chopstick[(i+1)mod 5]);又成功后便可进餐。进餐完毕,又先放下他左边的筷子,然后再放右边的筷子。

  • 存在的问题
    虽然上述解法可保证不会有两个相邻的哲学家同时进餐,但有可能引起死锁。假如五位哲学家同时饥饿而各自拿起左边的筷子时,就会使五个信号量chopstick均为0; 当他们再试图去拿右边的筷子时,都将因无筷子可拿而无限期地等待

  • 各种解决方案
    1) 至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕时能释放出他用过的两只筷子,从而使更多的哲学家能够进餐。
    (2) 仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐。
    (3) 规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子,而偶数号哲学家则相反。按此规定,将是1、2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。即五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。
    故用AND信号量机制可获得最简洁的解法

“ 读 者 — 写者问题”

  • 问题描述
    所谓“读者—写者问题(Reader-Writer Problem)”是指保证一个 Writer 进程必须与其他进程互斥地访问共享对象的同步问题。读者—写者问题常被用来测试新同步原语。

  • 解决
    为实现 Reader 与 Writer 进程间在读或写时的互斥而设置了一个互斥信号量 Wmutex。另外,再设置一个整型变量 Readcount 表示正在读的进程数目。由于只要有一个 Reader 进程在读,便不允许 Writer 进程去写。因此,仅当 Readcount=0,表示尚无 Reader 进程在读时,Reader进程才需要执行Wait(Wmutex)操作。若 Wait(Wmutex)操作成功,Reader进程便可去读,相应地,做 Readcount+1 操作。同理,仅当 Reader 进程在执行了 Readcount 减 1操作后其值为0时,才须执行signal(Wmutex)操作,以 便 让 Writer进程写。又因为Readcount是一个可被多个 Reader 进程访问的临界资源,因此,也应该为它设置一个互斥信号量rmutex。

wait(rmutex);if readcount=0 then wait(wmutex);    Readcount:=Readcount+1;signal(rmutex);perform read;wait(rmutex);readcount:=readcount-1;if readcount=0 then signal(wmutex);signal(rmutex);

这里的读者—写者问题与前面的略有不同,它增加了一个限制,即最多只允许RN个读者同时读。为此,又引入了一个信号量 L,并赋予其初值为 RN,通过执行 wait(L,1,1)操作,来控制读者的数目。每当有一个读者进入时,就要先执行 wait(L,1,1)操作,使 L的值减1。当有RN个读者进入读后,L便减为0,第RN+1个读者要进入读时,必然会因wait(L,1,1)操作失败而阻塞

进程通信

进程通信,是指进程之间的信息交换,其所交换的信息量少者是一个状态或数值,多者则是成千上万个字节。

应当指出,信号量机制作为同步工具是卓有成效的,但作为通信工具,则不够理想,主要表现在下述两方面: (1) 效率低,生产者每次只能向缓冲池投放一个产品(消息),消费者每次只能从缓冲区中取得一个消息; (2) 通信对用户不透明。

本节所要介绍的是高级进程通信,是指用户可直接利用操作系统所提供的一组通信命令高效地传送大量数据的一种通信方式。操作系统隐藏了进程通信的实现细节。或者说,通信过程对用户是透明的。这样就大大减少了通信程序编制上的复杂性。

目前,高级通信机制可归结为三大类:共享存储器系统、消息传递系统以及管道通信系统。

共享存储器系统

(1) 基于共享数据结构的通信方式。在这种通信方式中,要 求 诸 进程公用某些数据结构,借以实现诸进程间的信息交换。如在生产者—消费者问题中,就是用有界缓冲区这种数据结构来实现通信的。这里,公用数据结构的设置及对进程间同步的处理,都是程序员的职责。这无疑增加了程序员的负担,而操作系统却只须提供共享存储器。因此,这种通信方式是低效的,只适于传递相对少量的数据。
(2) 基于共享存储区的通信方式。为了传输大量数据,在存储器中划出了一块共享存储区,诸进程可通过对共享存储区中数据的读或写来实现通信。这种通信方式属于高级通信。

消息传递系统

消息传递系统(Message passing system)是当前应用最为广泛的一种进程间的通信机制。在该机制中,进程间的数据交换是以格式化的消息(message)为单位的;在计算机网络中,又把message称为报文

管道通信系统

  • 概念
    所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名pipe文件。向管道(共享文件)提供输入的发送进程(即写进程),以字符流形式将大量的数据送入管道;而接受管道输出的接收进程(即读进程),则从管道中接收(读)数据。由于发送进程和接收进程是利用管道进行通信的,故又称为管道通信

  • 管道机制必须提供以下三方面的协调能力:
    (1) 互斥,即当一个进程正在对pipe执行读/写操作时,其它(另一)进程必须等待。
    (2) 同步,指当写(输入)进程把一定数量(如4 KB)的数据写入pipe,便去睡眠等待,直到读(输出)进程取走数据后,再把它唤醒。当读进程读一空pipe时,也应睡眠等待,直至写进程将数据写入管道后,才将之唤醒。
    (3) 确定对方是否存在,只有确定了对方已存在时,才能进行通信。
    消息传递通信的实现方法

页面置换算法

Clock置换算法

改进型Clock置换算法

  • 改进思路
    在将一个页面换出时,如果该页已被修改过,便须将该页重新写回到磁盘上;但如果该页未被修改过,则不必将它拷回磁盘。在改进型 Clock算法中,除须考虑页面的使用情况外,还须再增加一个因素,即置换代价,这样,选择页面换出时,既要是未使用过的页面,又要是未被修改过的页面。把同时满足这两个条件的页面作为首选淘汰的页面。

  • 由访问位A和修改位M可以组合成下面四种类型的页面:
    1类(A=0,M=0):表示该页最近既未被访问,又未被修改,是最佳淘汰页。
    2类(A=0,M=1):表示该页最近未被访问,但已被修改,并不是很好的淘汰页。
    3类(A=1,M=0):表示该页最近已被访问,但未被修改,该页有可能再被访问。
    4类(A=1,M=1):表示该页最近已被访问且被修改,该页可能再被访问。

  • 具体流程
    (1) 从指针所指示的当前位置开始,扫描循环队列,寻找A=0且M=0的第一类页面,将所遇到的第一个页面作为所选中的淘汰页。在第一次扫描期间不改变访问位A。
    (2) 如果第一步失败,即查找一周后未遇到第一类页面,则开始第二轮扫描,寻找A=0且M=1的第二类页面,将所遇到的第一个这类页面作为淘汰页。在第二轮扫描期间,将所有扫描过的页面的访问位都置0。
    (3) 如果第二步也失败,亦即未找到第二类页面,则将指针返回到开始的位置,并将所有的访问位复0。然后重复第一步,如果仍失败,必要时再重复第二步,此时就一定能找到被淘汰的页。

0 0
原创粉丝点击