【计算机操作系统】第二章 进程管理

  • Post author:
  • Post category:其他



1 进程的基本概念

1.1 程序的顺序执行和特征




程序顺序执行时的特征

  1. 顺序性:处理机的操作严格按照程序所规定的顺序执行,即每一操作必须在上一个操作结束之后开始。
  2. 封闭性:程序是在封闭的环境下执行的,即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它。程序一旦开始执行,其执行结果不受外界因素影响。
  3. 可再现性:只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都将获得相同的结果。

1.2 前驱图

前趋图(Precedence Graph)是一个有向无循环图,记为 DAG(Directed Acyclic Graph),用于描述进程之间执行的前后关系。

应当注意,前趋图中必须不存在循环。(b)这种前趋关系是不可能满足的。

1.3 程序的并发执行和特征

并发不再做解释,上一章已经做了阐释。


程序并发执行时候的特征

程序的并发执行,虽然提高了系统吞吐量,但也产生了下述一些与程序顺序执行时不同的特征。(从资源使用的角度上来说)

  • 间断性
  • 失去封闭性
  • 不可再现性


1.4 进程的特征与状态

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

特征

加以描述。

  1. 结构特征->PCB进程控制块
  2. 动态性:“它由创建而产生,由调度而执行,由撤消而消亡”。可见,进程实体有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有运动的含义,因而是静态的。
  3. 并发性:
  4. 独立性:
  5. 异步性:



进程的三种基本状态:

进程执行时的间断性决定了进程可能具有多种状态。事实上,运行中的进程可能具有以下三种基本状态。

1) 就绪(Ready)状态

当进程已分配到

除 CPU 以外的所有必要资源后

,只要再获得 CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列。

2) 执行状态


进程已获得 CPU,其程序正在执行

。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。

3) 阻塞状态


正在执行的进程由于发生某事件而暂时无法继续执行时

,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。致使进程阻塞的典型事件有:请求 I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。

挂起状态:在另一些系统中,又增加了一些新状态,最重要的是挂起状态。

可参考:

进程的特征与状态

1.5 进程控制快 PCB

为了描述和控制进程的运行,系统为每个进程定义了一个数据结构——

进程控制块PCB(Process Control Block)

,它是进程实体的一部分,是操作系统中最重要的记录型数据结构。


进程控制块的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。

Linux 系统中用task_struct 数据结构来描述每个进程的进程控制块。

进程控制快中的信息:

  1. 进程标示符;
  2. 处理机状态;
  3. 进程调度信息;
  4. 进程控制信息。

进程控制块的组织方式

在一个系统中,通常可拥有数十个、 数百个乃至数千个 PCB。为了能对它们加以有效的管理,应该用适当的方式将这些 PCB 组织起来。

链接方式:把具有同一状态的 PCB,用其中的链接字链接成一个队列。

索引方式:系统根据所有进程的状态建立几张索引表。并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。


2 进程控制

进程控制是进程管理中最基本的功能。它用于创建一个新进程,终止一个已完成的进程,或终止一个因出现某事件而使其无法运行下去的进程,还可负责进程运行中的状态转换。

原语(Primitive)是由若干条指令组成的,用于完成一定功能的一个过程。它与一般过程的区别在于:它们是“原子操作(Action Operation)”。

所谓原子操作,是指一个操作中的所有动作要么全做,要么全不做。

2.1 进程的创建

引起创建进程的事件:

  1. 用户登录
  2. 作业调度
  3. 提供服务
  4. 应用请求

进程创建的过程:

  1. 申请空白PCB;
  2. 为新进程分配资源;
  3. 初始化进程控制块;
  4. 将新进程插入就绪队列。

2.2 进程的终止

引起进程终止的事件:

  1. 正常结束;
  2. 异常结束;
  3. 外界干预;

进程终止的过程:如果系统中发生了上述要求终止进程的某事件,OS 便调用进程终止原语,按下述过程去终止指定的进程。

  • (1) 根据被终止进程的标识符,从 PCB 集合中检索出该进程的 PCB,从中读出该进程的状态。
  • (2) 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度。
  • (3) 若该进程还有子孙进程,还应将其所有子孙进程予以终止,以防它们成为不可控的进程。
  • (4) 将被终止进程所拥有的全部资源,或者归还给其父进程,或者归还给系统。
  • (5) 将被终止进程(PCB)从所在队列(或链表)中移出,等待其他程序来搜集信息。

2.3 进程的阻塞和唤醒

引起进程阻塞和唤醒的事件

  1. 请求系统服务;
  2. 启动某种操作;
  3. 新数据尚未到达
  4. 无新工作可做;

进程阻塞过程

正在执行的进程,当发现上述某事件时,由于无法继续执行,于是进程便通过调用阻塞原语 block 把自己阻塞。

进程唤醒过程

当被阻塞进程所期待的事件出现时,如 I/O 完成或其所期待的数据已经到达,则由有关进程(比如用完并释放了该 I/O 设备的进程)调用唤醒原语 wakeup( ),将等待该事件的进程唤醒。

2.4 进程的挂起与激活

挂起:当出现了引起进程挂起的事件时,系统将利用挂起原语 suspend( )将指定进程或处于阻塞状态的进程挂起。挂起原语的执行过程是:首先检查被挂起进程的状态,若处于活动就绪状态,便将其改为静止就绪; 对于活动阻塞状态的进程,则将之改为静止阻塞。为了方便用户或父进程考查该进程的运行情况而把该进程的 PCB 复制到某指定的内存区域。最后,若被挂起的进程正在执行,则转向调度程序重新调度。

激活:当发生激活进程的事件时,系统将利用激活原语 active( )将指定进程激活。激活原语先将进程从外存调入内存,检查该进程的现行状态,若是静止就绪,便将之改为活动就绪;若为静止阻塞,便将之改为活动阻塞。假如采用的是抢占调度策略,则每当有新进程进入就绪队列时,应检查是否要进行重新调度,即由调度程序将被激活进程与当前进程进行优先级的比较,如果被激活进程的优先级更低,就不必重新调度;否则,立即剥夺当前进程的运行,把处理机分配给刚被激活的进程。


3 进程同步

在 OS 中引入进程后,虽然提高了资源的利用率和系统的吞吐量,但由于进程的异步性,也会给系统造成混乱,尤其是在他们争用临界资源时。

进程同步的主要任务是对多个相关进程在执行次序上进行协调,以使并发执行的诸进程之间能有效地共享资源和相互合作,从而使

程序的执行具有可再现性。

3.1 进程同步概念

1.两种形式的制约关系

在多道程序环境下,当程序并发执行时,由于资源共享和进程合作,使同处于一个系统中的诸进程之间可能存在着以下两种形式的制约关系。

(1) 间接相互制约关系。同处于一个系统中的进程,通常都共享着某种系统资源,如共享 CPU、共享 I/O 设备等。所谓间接相互制约即源于这种资源共享,例如,有两个进程 A和 B,如果在 A 进程提出打印请求时,系统已将惟一的一台打印机分配给了进程 B,则此

时进程 A 只能阻塞;一旦进程 B 将打印机释放,则 A 进程才能由阻塞改为就绪状态。

(2) 直接相互制约关系。这种制约主要源于进程间的合作。例如,有一输入进程 A 通过单缓冲向进程 B 提供数据。当该缓冲空时,计算进程因不能获得所需数据而阻塞,而当进程 A 把数据输入缓冲区后,便将进程 B 唤醒;反之,当缓冲区已满时,进程 A 因不能再向缓冲区投放数据而阻塞,当进程 B 将缓冲区数据取走后便可唤醒 A。

2. 临界资源

多道程序系统中存在许多进程,它们共享各种资源,然而有很多资源一次只能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。许多物理设备都属于临界资源,如输入机、打印机、磁带机等。

3.临界区

人们把在每个进程中访问临界资源的那段代码称为临界区(critical section)。显然,若能保证诸进程互斥地进入自己的临界区,便可实现诸进程对临界资源的互斥访问。

4.同步机制应遵循的规则

为实现进程互斥地进入自已的临界区,可用软件方法,更多的是在系统中设置专门的同步机构来协调各进程间的运行。所有同步机制都应遵循下述四条准则:

(1) 空闲让进。当无进程处于临界区时,表明临界资源处于空闲状态,应允许一个请求进入临界区的进程立即进入自己的临界区,以有效地利用临界资源。

(2) 忙则等待。当已有进程进入临界区时,表明临界资源正在被访问,因而其它试图进入临界区的进程必须等待,以保证对临界资源的互斥访问。

(3) 有限等待。对要求访问临界资源的进程,应保证在有限时间内能进入自己的临界区,以免陷入“死等”状态。

(4) 让权等待。当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”状态。

3.2 信号量机制

信号量(Semaphores)机制是一种卓有成效的进程同步工具。

很好的文章,可以阅读一下:

第二章 信号量机制及几个经典例题






操作系统之信号量机制总结




3.3 信号量的应用

  1. 利用信号量实现进程互斥;
  2. 利用信号量实现前驱关系。

3.4 管程机制

虽然信号量机制是一种既方便、又有效的进程同步机制,但每个要访问临界资源的进程都必须自备同步操作 wait(S)和 signal(S)。这就使大量的同步操作分散在各个进程中。这不仅给系统的管理带来了麻烦,而且还会因同步操作的使用不当而导致系统死锁。这样,在解决上述问题的过程中,便产生了一种新的进程同步工具——管程(Monitors)。

利用共享数据结构抽象地表示系统中的共享资源,而把对该共享数据结构实施的操作定义为一组过程,如资源的请求和释放过程 request 和 release。

代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成了一个操作系统的资源管理模块,我们称之为管程。

可以阅读:

什么是管程,管程机制及其使用方法详解

+

管程机制浅析


4 经典进程的同步问题


进程同步——经典的同步问题


操作系统之经典进程同步问题

  1. 生产者—消费者问题
  2. 哲学家进餐问题
  3. 读者—写者问题

5 进程通信

进程通信,是指进程之间的信息交换,其所交换的信息量少者是一个状态或数值,多者则是成千上万个字节。进程之间的互斥和同步,由于其所交换的信息量少而被归结为低级通信。在进程互斥中,进程通过只修改信号量来向其他进程表明临界资源是否可用。在生产者—消费者问题中,生产者通过缓冲池将所生产的产品传送给消费者。

5.1 进程通讯的类型

  1. 共享存储器系统;
  2. 消息传递系统;
  3. 管道通信(所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名 pipe 文件。);

5.2 消息传递通信的实现方法

  1. 直接通信方式;
  2. 间接通信方式。

5.3 消息传递系统实现中的若干问题

5.4  消息缓冲队列通信机制

  1. 通信链路
  2. 消息的格式
  3. 进程同步方式

Re:

操作系统课程设计 消息缓冲队列通信


6 线程

如果说,在操作系统中引入进程的目的,是为了使多个程序能并发执行,以提高资源利用率和系统吞吐量,那么,在操作系统中再引入线程,则是为了减少程序在并发执行时所付出的时空开销,使 OS 具有更好的并发性。

由于进程是一个资源的拥有者,因而在创建、撤消和切换中,系统必须为之付出较大的时空开销。正因如此,在系统中所设置的进程,其数目不宜过多,进程切换的频率也不宜过高,这也就限制了并发程度的进一步提高。


线程与进程的比较


线程具有许多传统进程所具有的特征,所以又称为轻型进程(Light-Weight Process)或进程元,相应地把传统进程称为重型进程(Heavy-Weight Process),传统进程相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个线程。下面我们从调度性、并发性、系统开销和拥有资源等方面对线程和进程进行比较。

1) 调度

在传统的操作系统中,作为拥有资源的基本单位和独立调度、分派的基本单位都是进程。而在引入线程的操作系统中,则把线程作为调度和分派的基本单位,而进程作为资源拥有的基本单位,把传统进程的两个属性分开,使线程基本上不拥有资源,这样线程便能

轻装前进,从而可显著地提高系统的并发程度。在同一进程中,线程的切换不会引起进程的切换,但从一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

2) 并发性

在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间亦可并发执行,使得操作系统具有更好的并发性,从而能更加有效地提高系统资源的利用率和系统的吞吐量。例如,在一个未引入线程的单 CPU 操作系统中,若仅设置一个

文件服务进程,当该进程由于某种原因而被阻塞时,便没有其它的文件服务进程来提供服务。在引入线程的操作系统中,则可以在一个文件服务进程中设置多个服务线程。当第一个线程等待时,文件服务进程中的第二个线程可以继续运行,以提供文件服务;当第二个线程阻塞时,则可由第三个继续执行,提供服务。显然,这样的方法可以显著地提高文件服务的质量和系统的吞吐量。

3) 拥有资源

不论是传统的操作系统,还是引入了线程的操作系统,进程都可以拥有资源,是系统中拥有资源的一个基本单位。一般而言,线程自己不拥有系统资源(也有一点必不可少的资源),但它可以访问其隶属进程的资源,即一个进程的代码段、数据段及所拥有的系统资源,如已打开的文件、I/O 设备等,可以供该进程中的所有线程所共享。

4) 系统开销

在创建或撤消进程时,系统都要为之创建和回收进程控制块,分配或回收资源,如内存空间和 I/O 设备等,操作系统所付出的开销明显大于线程创建或撤消时的开销。类似地,在进程切换时,涉及到当前进程 CPU 环境的保存及新被调度运行进程的 CPU 环境的设置,而线程的切换则仅需保存和设置少量寄存器内容,不涉及存储器管理方面的操作,所以就切换代价而言,进程也是远高于线程的。此外,由于一个进程中的多个线程具有相同的地址空间,在同步和通信的实现方面线程也比进程容易。在一些操作系统中,线程的切换、同步和通信都无须操作系统内核的干预。


线程的属性


在多线程 OS 中,通常是在一个进程中包括多个线程,每个线程都是作为利用 CPU 的基本单位,是花费最小开销的实体。线程具有下述属性。

(1) 轻型实体。线程中的实体基本上不拥有系统资源,只是有一点必不可少的、 能保证其独立运行的资源,比如,在每个线程中都应具有一个用于控制线程运行的线程控制块TCB,用于指示被执行指令序列的程序计数器,保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。

(2) 独立调度和分派的基本单位。在多线程 OS 中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很“轻”,故线程的切换非常迅速且开销小。

(3) 可并发执行。在一个进程中的多个线程之间可以并发执行,甚至允许在一个进程中的所有线程都能并发执行;同样,不同进程中的线程也能并发执行。

(4) 共享进程资源。在同一进程中的各个线程都可以共享该进程所拥有的资源,这首先表现在所有线程都具有相同的地址空间(进程的地址空间)。这意味着线程可以访问该地址空间中的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。

6.1 线程间的同步和通信

为使系统中的多线程能有条不紊地运行,在系统中必须提供用于实现线程间同步和通信的机制。为了支持不同频率的交互操作和不同程度的并行性,

在多线程 OS 中通常提供多种同步机制,如互斥锁、条件变量、计数信号量以及多读、单写锁等。

1.互斥锁(mutex)

互斥锁是一种比较简单的、用于实现线程间对资源互斥访问的机制。由于操作互斥锁的时间和空间开销都较低,因而较适合于高频度使用的关键共享数据和程序段。互斥锁可以有两种状态,即开锁(unlock)和关锁(lock)状态。相应地,可用两条命令(函数)对互斥锁进

行操作。其中的关锁 lock 操作用于将 mutex 关上,开锁操作 unlock 则用于打开 mutex。

2.条件变量

3.信号量机制

前面所介绍的用于实现进程同步的最常用工具——信号量机制,也可用于多线程 OS中,实现诸线程或进程之间的同步。为了提高效率,可为线程和进程分别设置相应的信号量。

6.2 线程的实现方式

线程已在许多系统中实现,但各系统的实现方式并不完全相同。在有的系统中,特别是一些数据库管理系统如 Infomix,所实现的是用户级线程(UserLevel Threads);而另一些系统(如 Macintosh 和 OS/2 操作系统)所实现的是内核支持线程(KernelSupported Threads); 还有一些系统如 Solaris 操作系统,则同时实现了这两种类型的线程。

1.内核支持线程:这里所谓的内核支持线程 KST(Kernel Supported Threads),也都同样是在内核的支持下运行的,即无论是用户进程中的线程,还是系统进程中的线程,他们的创建、撤消和切换等也是依靠内核,在内核空间实现的。

2.用户级线程:用户级线程 ULT(User Level Threads)仅存在于用户空间中。对于这种线程的创建、撤消、线程之间的同步与通信等功能,都无须利用系统调用来实现。对于用户级线程的切换,通常发生在一个应用进程的诸多线程之间,这时,也同样无须内核的支持。




版权声明:本文为HelloZEX原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。