操作系统 进程

概述

进程管理,也称为处理机管理。

在多道程序(Multiprogram)批处理系统和分时系统中有多个并发执行的程序,为了描述系统中程序执行的动态引入了进程。进程是操作系统中最古老最核心的概念,它是资源分配和独立运行的基本单位。其重点在于管理进程间的并发、合作及资源竞争问题。

程序与进程

描述进程之间的先后执行顺序通常可以使用前趋图(Precedence Graph),它是一种有向无环图(DAG, Directed Acyclic Graph)。它由结点和有向边组成,其中结点代表不同程序段的操作,边代表两个程序段之间是否存在前趋关系。

如程序段 P i P_i Pi P j P_j Pj间的前趋关系可表示为 P i → P j P_i \rightarrow P_j PiPj,可称 P i P_i Pi P j P_j Pj的前趋, P j P_j Pj P i P_i Pi的后继,其含义代表为 P i P_i Pi执行完毕后才可以执行 P j P_j Pj。这个图类似于“关键路径”。

顺序/并发执行的特征

顺序执行

顺序执行十分简单,一个典型的程序段前趋图如下:

PG 1

顺序执行的特征主要是:顺序性、封闭性、可再现性

并发执行

使顺序执行的程序并发的执行3个作业,则其前趋图如下:

PG 2

可以看到,比顺序略微复杂一些,但也很直观,这个模式与指令的流水是类似的。

C1I2并行,O1, C2, I3并行等,另外,在这种情况中称[I2, I3], [C2, C3], [O2, O3]I1, C1, O1间接约束;而C1, O1I1直接制约,其他情况以此类推。

并发执行的特征如下:

  1. 程序失去封闭性
  2. 程序和机器执行程序的活动不再一一对应
  3. 并发程序间存在互相制约

前两者主要体现在进程间对资源的争用时引发的错误。

进程的组成

进程是程序的一次执行,一个进程通常由程序、数据、和进程控制块(PCB, Process Control Block)(也有一些书籍将PCB称为进程表(Process table))组成

其中程序部分是程序本身,这一部分通常是不可修改的,这使的一个程序被多个进程同时执行是可能的。

而数据部分则是程序执行时所需要的数据和工作区域,这一部分对每个进程都是独享的,是进程可修改的部分。

而PCB则是用来标识进程信息的,对每个进程而言也是唯一的,其内容在不同的操作系统可能是不一样的,但主要内容如下表:

字段含义
进程标识符(PID, Process Identifier)标识操作系统中各个进程
状态进程当前状态
位置信息程序及数据所在主存、外存中位置
控制信息参数、信号量、消息等
队列指针链接同一状态的进程
优先级操作系统对进程调度的依据
现场保护区在程序中断或暂停时存放程序执行状态,以便程序可以恢复运行

进程状态及状态间转换

尽管进程都是独立的实体,有属于自己的程序计数器及内部状态等。但有时候进程间需要相互协作,如一个进程输出的信息是另一个进程的输入信息,当前者尚未输出结果时,后者就必须阻塞等待输入到来才能继续执行。

为了方便理解和描述,通常使用进程模型来形容进程在执行时状态的变化。

三态/五态模型

三态模型将进程状态描述为三种,也是最基本的三种,见下图:

Process Triple State model

其含义如下表:

状态含义
运行进程在处理机上运行时,则为运行状态,对于单处理机系统仅有一个进程会处于运行状态。
就绪进程获得了除处理机之外的所有资源,一旦处理机可用就可以执行。
阻塞进程正在等待事件的发生(如等待I/O完成)而暂停运行,把处理机资源分配给该进程也无法执行。

除此之外还有一种五态模型,它只是稍微细化了三态模型,见下图:

Process Quintuple State Model

多出来的两个状态含义如下表:

状态含义
新建进程刚被创建,正在等待操作系统完成填充管理进程所需信息。
终止进程执行完毕,正在等待操作系统回收资源。

进程的控制

进程的控制即对系统中所有进程从创建到消亡全过程的控制,进程的控制主要是由操作系统 内核(Kernel) 中的 原语(Primitive) 实现的。

内核是计算机硬件的第一层扩充,是操作系统的最小组成。

原语则是由若干条机器指令组成用于完成特定功能的程序段,其特点在于原语是不可分割的,要执行就会把该原语程序段全部执行,无法选择的执行。

进程间通信(IPC, Inter Process Communication)

很多时候一个进程需要其他进程共同协同工作,但不可避免的会出现冲突,如争用资源就会使的程序行为不可预期。因此需要一些机制来解决这些问题。

进程间同步(Synchronization)

若进程A、B通过共享同一块空间协同工作,若进程B需要等待进程A填充数据至共享的空间才能继续执行,这时候就需要等待。

进程间需要相互合作,协同的过程,就称为进程的同步。

进程间互斥(Mutual Exclusion)

若进程A、B需要均需要使用一次只能供一个进程使用的资源(如打印机)时,就存在资源争用的问题。这种资源也称为临界资源(Critical Resource)

进程间的这种关系就称为进程间的互斥。

临界区(CS, Critical Section)

进程中对临界资源实施操作的那段程序的区域就是临界区。对互斥临界区有4条原则:

  1. 有空即进——当无进程处于临界区时,允许进程进入,并且只能在临界区运行有限时间。
  2. 无空则等——当有进程位于临界区,其他想要进入临界区的进程必须等待,保证资源不被多个进程同时使用。
  3. 有限等待——对于要求访问临界区的进程,应保证进程能在有限时间内进入。
  4. 让权等待——当进程无法进入临界区时,应立即释放处理机资源,避免进程进入无用的忙等待。

信号量(Semaphore)机制

为了解决进程间同步/互斥的问题,Dijkstra(就是提出图最短路算法的学者)于1965年提出信号量这种有效的进程同步/互斥工具。

目前,信号量机制已经有了很大的发展,主要与整型信号量、记录型信号量、信号量集机制。

整型信号量

信号量是整型变量,根据控制对象不同赋予不同的值。其主要分为两类:

  1. 公用信号量——实现进程间互斥,初值为1或资源的数量
  2. 私用信号量——实现进程间同步,初值为0或任一正整数。

信号量 S S S的含义为: S ≥ 0 S \geq 0 S0时表示某资源可用数, S &lt; 0 S &lt; 0 S<0则其绝对值表示阻塞队列中等待的进程数。

PV操作

系统中的进程,工作的正确与否不仅取决于其自身,还与它是否能正确与其他相关进程实施同步互斥有关。PV操作是用来实现同步和互斥的常用方法,P和V操作均是来自硬件的低级通信原语,在执行期间不可分割,以此保证不会因为时间片轮转或其他因素造成意外。

P操作定义 S : = S − 1 S:=S-1 S:=S1,若 S ≥ 0 S \geq 0 S0,则执行P操作的进程继续执行;若 S &lt; 0 S &lt; 0 S<0,则该进程进入阻塞状态,并置入阻塞队列。

V操作定义 S : = S + 1 S:= S+1 S:=S+1,若 S &gt; 0 S&gt;0 S>0,则执行V操作的进程继续执行;若 S ≤ 0 S \leq 0 S0,则从阻塞队列中唤醒一个进程,将其置入就绪队列,执行V操作的进程继续。

利用PV操作实现进程互斥/同步

互斥就是令信号量mutex的初值为1,当进入临界区时执行P操作,退出临界区时执行V操作。

P(mutex)
   临界区
V(mutex)

同步则是将信号量与消息产生联系,若信号量为0时则表示消息未产生,反之则代表消息已存在。进程通过调用P操作测试消息是否准备好,调用V操作知会消息已准备好。

一些例子

这里引用一个很经典的例子,生产者消费者问题,生产者进程 P 1 P_1 P1需要将生产好的产品不断的送入缓冲区,而消费者进程 P 2 P_2 P2则从缓冲区中消费产品。

首先通过使用同步的方式来实现这个过程,需要设置两个信号量S1, S2,其中S1的初值为1,表示缓冲区空,可以将产品送入缓冲区;而信号量S2的初值为0,表示缓冲区有产品。其过程如下流程。

Created with Raphaël 2.2.0 P1 生产一个产品 P(S1) 将产品送入缓冲区 V(S2)
Created with Raphaël 2.2.0 P2 P(S2) 从缓冲区取产品 V(S1) 消费产品

假设缓冲区有上限n,也可以通过信号量加互斥的方式实现:

设置3个信号S, S1, S2,其中S为互斥信号,初值为1S1表示是否可以将产品放入缓冲,初值为nS2表示缓冲区中是否有产品,初值为0。流程如下:

Created with Raphaël 2.2.0 P1 生产一个产品 P(S1) P(S) 将产品送入缓冲区 V(S) V(S2)
Created with Raphaël 2.2.0 P2 P(S2) P(S) 从缓冲区取产品 V(S) V(S1) 消费产品

互斥量(Mutex)

如果不需要信号量的计数能力,则可以使用信号的简化,称为互斥量。它不包含计数能力,其基本操作称作加锁及解锁,行为与信号量类似,当对一个已加锁的信号量再次加锁则会阻塞线程,它使用起来更为简便。

高级通信原语

虽然讲的是进程间信息交换,但上面提及的PV操作显然不适合用于进程间数据交换,它只是为了解决同步与互斥问题。

为了实现进程间的数据通信,使能传递大量数据,操作系统引入了高级通信原语。主要通过如下方式实现进程间通信:

  1. 共享存储模式

    通信间进程共享某些存储区域,以实现通信。(同时还需要考虑冲突问题,因此通常需要同时使用互斥量)

  2. 消息传递模式

    以消息为单位在进程间传递信息,类似于网络通信。

  3. 管道通信

    通过连接一个读进程,一个写进程。以实现它们之间通信的共享文件(pipe文件),逻辑上来看这就是一个管道。可以看做写进程往管道中源源不断的输入字符流,而读进程则从管道中取出这些信息,就像水管一样。

线程(Thread)

线程是一种轻量的进程,传统的进程有两个基本属性:资源独立、调度独立。但进程的创建、切换等操作需要耗费较多的时间。

为了缓解这个问题,引入了线程这一概念。它将进程的两个基本属性拆分,进程作为资源独立的基本单位,线程则作为调度独立的基本单位。线程仅拥有程序运行必备的资源(如程序计数器、寄存器、栈),线程可与同属一个进程的其他线程共享进程所拥有的资源。通过一个进程内有多个线程、线程可以创建另外一个线程的方式,很多情况下就可以无需频繁切换进程,大大提高了并发的效率。

线程与进程一样,也有三态模型,线程拥有与进程很多类似的特性,所以也称为轻型进程(Light-Weight Process)

线程也分为 用户级线程(User-Level Threads)内核支持线程(Kernel-Supported Threads) 两类,前者不依赖内核,其创建、销毁、切换都不需要通过系统调用完成;而后者则依赖内核,其创建、销毁、切换都需要依赖系统内核完成;有些操作系统同时实现了两种类型的线程。

而进程的切换不管是系统进程还是用户进程,均需要由系统内核调度。因此无论什么进程都与内核相关,所以线程与进程在本质上是不同的。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值