前言:在计算机操作系统中,进程是资源分配的基本单位,也是独立运行的基本单位
1、进程的定义
- 进程是程序在处理器上的一次执行过程
- 进程是可以和别的进程并行执行的计算
- 进程是程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个独立的单位
- 进程可定义为一个数据结构及能在其上操作的一个程序
- 进程是一个程序关于某个数据集合在处理器上顺序执行所发生的活动。
- 上述这些描述从不同角度对进程进行了阐述,尽管各有侧重,但本质是相同的
2、进程的特征
- 动态性:进程是在处理器上的一次执行过程,因而是动态的。动态特性还表现在它因创建而产生,由调度而执行,因得不到资源而暂停,最后因撤销而消亡
- 并发性:指多个进程同时存在于内存中,能在一段时间内同时运行。引入进程的目的是使程序能与程序并发执行,以提高资源的利用率
- 独立性:进程是一个能独立进行的基本单位,也是系统进行资源分配和调度的独立单位
- 异步性:进程以各自独立的、不可预知的速度向前推进
- 结构特征:为了描述和记录进程的运动变化过程,并使之能正确运行,应为每个进程配置一个进程控制块(Process Control Block,PCB),这样从结构上看,每个进程都由程序段、数据段和一个进程控制块组成。
3、进程和程序的关系
- 进程是动态的,程序是静止的。进程是程序的执行:程序是有序代码的集合
- 进程是暂时的,程序是永久的。进程是一个状态变化的过程;程序可以长久保存
- 进程与程序的组成不同:进程的组成包括程序、数据和进程控制块
- 进程与程序是密切相关的。通过多次执行,一个程序可以对应多个进程:通过调用关系,一个进程可以包括多个程序。进程可以创建其他进程,而程序不能形成新的程序
4、进程的组成
- 进程控制块(PCB):每个进程均有一个PCB,它是一个技能标识进程的存在、又能刻画执行瞬间特征的数据机构。当进程被创建时,系统为它申请和构造一个相应的PCB
- 程序段:是进程中能被进程调度到CPU上执行的程序代码段,它能实现相应的特定功能
- 数据段:一个进程的数据段可以是进程对应的程序加工处理的原始数据,也可以是程序执行时产生的中间或结果数据
5、操作系统的内核:
操作系统的内核是基于硬件的第一次软件扩充。在现代操作系统设计中,往往把一些与硬件紧密相关的模块或运行频率较高的模块以及许多模块所共用的一些基本操作安排在靠近硬件的软件层次中,并使它们常驻内存,以提高操作系统的运行效率,通常把这部分成为操作系统的内核。内核是基于硬件的第一层软件扩充,它为系统控制和进程管理提供了良好的环境
6、线程的概念
(1)线程的引入
如果说,在操作系统中引入进程的目的是使多个程序并发执行,以改善资源利用率及提高系统吞吐量;那么,在操作系统中再引入线程,则是为了减少程序并发执行时所付出的时空开销,使操作系统具有更好的并发性。为了说明它,我们再提一下进程的两个基本属性
- 进程是一个拥有资源的独立单元
- 进程同时又是一个可以被处理器独立调度和分配的单元
上述两个属性构成了程序并发执行的基础。然而为了使进程能并发执行,操作系统还必须进行一系列的操作,如创建进程、撤销进程和进程切换。在进行这些操作时,操作系统要为进程分配资源和回收资源,为运行进程保存现场信息,这些工作都需要付出较多的时间开销。正因为如此,在系统中不宜设置过多的进程,进程切换的频率也不能太高,从而限制了系统并发程度的进一步提高
为了使多个程序更好的并发执行,并尽量减少操作系统的开销,不少操作系统研究者考虑将进程的两个属性分离开,分别交由不同的实体来实现。为此,操作系统的设计者一如了线程,让线程去完成第二个基本属性的任务,而进程只完成第一个基本属性的任务
(2)线程的定义
线程的定义与进程类似,存在多种不同的提法。这些提法可以相互补充对线程的理解
- 线程是进程内的一个执行单元,比进程更小
- 线程是进程内的一个可调度实体
- 线程是程序(或进程)中相对独立的一个控制流序列
- 线程与本身不能单独运行,只能包含在进程中,只能在进程中执行
- 综上所述,不妨将线程定义为:线程是进程内一个相对独立的、可调度的执行单元。线程自己基本不拥有资源,只拥有一点在运行时必不可少的资源(如程序计数器、一组寄存器和栈),但他可以与同属于一个进程的其他线程共享进程拥有的全部资源
- 多线程是指一个进程中由多个线程,这些线程共享该进程资源。这些线程主流在相同的地址文件中,共享数据和文件。如果一个线程修改了一个数据项,其他线程可以了解和使用此结果数据。一个线程打开并读一个文件时,同一进程中的其他线程也可以同时读此文件
(3)线程的实现
在操作系统有多种方式可实现对线程的支持。最自然的方法是由操作系统内核提供线程的控制机制。在只有进程概念的操作系统中,可由用户程序利用函数库提供线程的控制机制。还有一种做法时同时在操作系统内核和用户程序两个层次上提供线程控制机制
内核级线程是指依赖于内核,由操作系统内核完成创建和撤销工作的线程。在支持内核级线程的操作系统中,内核维护进程和线程的上下文信息并完成线程切换工作。一个内核级线程由于I/O操作而阻塞时,不会影响到其他线程的运行。这时,处理器时间片分配对象是线程,所以由多个线程的进程将获得更多处理器时间
用户及线程是指不依赖于操作系统核心,由应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制的线程。由于用户级线程切换不需要内核特权,用户及线程调度算法可针对应用优化,在许多应用软件中都有自己的用户级线程。由于用户级线程的调度在应用进程内部进行,通常采用非抢占式和更见的的规则,也无需用户态/核心态切换,因此速度特别快。当然由于操作系统内核不了解用户线程的存在,当一个线程阻塞时,整个进程都必须等待。这时处理器时间片时分配给进程的,进程内有多个线程时每个线程的执行时间相对减少
在有些操作系统中,提供了上述两种方法的组合实现。在这种系统中,内核支持多线程的建立、调度与管理:同时,系统中又提供使用线程库的便利,允许用户应用程序建立、调度和管理用户级的线程由于同时提供内核线程控制机制和用户线程库,因此可以很好的将内核级线程和用户线程的优点结合起来
7、线程与进程的比较
- 调度:在传统的操作系统中拥有资源和独立调度的基本单位都是进程,而在引入线程的操作系统中,线程时独立调度的基本单位,进程是资源拥有的基本单位。在同一进程中,线程的切换不会引起进程切换。在不同的进程中进行线程切换,如从一个进程内的线程切换到另一个进程的线程中,将会引起进程切换
- 拥有资源:不论是传统操作系统还是设有线程的操作系统,进程都是拥有资源的基本单位,而线程不拥有系统资源(也有一点必不可少的资源,并非什么资源都没有),但线程可以访问其隶属进程的系统资源
- 并发性:在引入线程的操作系统中,不仅进程之间可以并发执行,并且同一进程内的多个线程也可以并发执行。从而使操作系统具有更好的并发性,大大提高了系统的吞吐量
- 系统开销:由于创建进程或撤销进程时,系统都要为止分配或回收资源,如内存空间、I/O设备等,操作系统所付出的开销远大于创建或撤销线程的开销。类似的,在进行线程切换时,涉及整个当前进程CPU环境的保存及新调度到进程的CPU环境的设置;而线程切换时,秩序保存和设置少量寄存器内容,因此开销很小。另外,由于同一进程内的多个线程共享进程的地址空间,因此,多线程之间的同步与通信非常容易实现,甚至无需操作系统的干预
8、多线程模型
有些系统同时支持用户级线程和内核级线程,因此根据用户级线程和内核级线程连接方式的不同产生了三种不同的多线程模型
多对一模型:多对一模型将多个用户级线程映射到一个内核级线程上。在采用该模型的系统中,线程在用户空间进行管理,效率相对较高。但是,由于多个用户级线程映射到一个内核级线程,只要一个用户级线程阻塞,就会导致整个进程阻塞。而且由于系统只能识别一个线程(内核级线程),因此即使由多处理器,该进程的若干用户级线程也只能同时运行一个,不能并行执行
一对一模型:一对一模型将内核级线程与用户级线程一一对应。这样做的好处是当一个线程阻塞时不影响其他其他线程的运行,因此并发性比多对一模型更好而且这样做之后,在多处理器上可以实现多线程并行。这种模型的缺点时创建一个用户及线程时需要创建一个相应的内核级线程
多对多模型:多对多模型将多个用户及线程映射到多个内核级线程(内核级线程数不多于用户级线程数,内核级线程数根据具体情况确定)。采用这样的模型可以打破前两种模型对用户级线程的限制,不仅可以是多个用户级线程真正意义上并行执行,而且不会限制用户级线程的数量。用户可以自由创建所需的用户级线程,多个内核级线程根据需要调用用户级线程,当一个用户级线程阻塞时,可以调度执行其他线程
9、进程通信
进程通信是指进程之间的信息交换。进程的互斥与同步就是一种进程间的通信方式。由于进程互斥与同步交换的信息量较少且效率较低,因此称这两种进程通信方式为低级进程通信方式,相应地,也可以将P,V原语称为两条低级进程通信原语。
目前,高级进程通信方式可以分为三大类:共享存储器系统、消息传递系统以及管道通信系统
(1)共享存储器系统
为了传输大量数据,在存储器中划入一块共享存储区,多个进程可以通过对共享存储区进行读写来实现通信。进程在通信前,向系统申请建立一个共享存储区,并指定该共享存储区的关键字。若该共享存储区已经建立,则将共享存储的描述符返回给申请者。然后,申请者把获得的共享存储区附加到进程上。这样进程便可以像读写普通寄存器一样读写共享存储区了。
(2)消息传递系统
在消息传递系统中,进程间以消息为单位交换数据,用户直接给系统提供的一组通信命令(原语)来实现通信,操作系统隐藏了通信的实现细节,简化了通信程序,得到了广泛应用。根据实现方式不同,消息传递系统可以分为以下两类:
直接通信方式:发送进程直接把消息发送给接受进程,并将它挂在接收进程的纤细缓冲队列上,接收进程从消息缓冲区队列中取得消息:
间接通信方式:发送进程消息发送到某个中间实体(通常称为信箱)中,接受进程从中取得消息。这种通信方式又称为信箱通信方式。该通信方式广泛应用于计算机网络中,相应的通信系统称为电子邮件系统
(3)管道通信系统
管道是连接读进程和写进程的以实现他们之间通信的共享文件,相关到提供输入的发送进程(即写进程)以字符流形式将大量的数据送入管道,而接收管道输出的进程(即读进程)可以从管道中接收数据
注意:管道是一个共享文件,不能单纯的从字面上理解管道只是一个传输通道
10、进程同步的基本概念
在学习进程同步之前,先介绍一些关键的概念
(1)两种形式的制约关系
间接相互制约关系(互斥)
若某一进程要求使用某种资源,而该资源正被另一进程使用,并且这一资源不允许两个进程同时使用,那么该进程只好等待已占用资源的进程释放资源后再使用。这种制约关系的基本形式是“进程-资源-进程”
这种制约关系源于多个同种进程需要互斥地共享某种系统资源(比如打印机),互斥是设置在同种进程之间以达到互斥的访问资源的目的(比如在生产者-消费者问题中,生产者与消费者需要互斥地访问缓冲池)。
直接相互制约关系(同步)
某一进程收不到另一进程给他提供的必要信息就不能继续运行下去,这种情况表明了两个进程之间在某个点上要交换信息,相互交流运行情况。这种制约关系的基本形式是“进程-进程
这种制约主要源于进程间的合作,同步设置在不同进程之间以达到多种进程间的同步”(比如在生产者消费者问题中,生产者就可以生产产品并放入缓冲池,消费者从缓冲池取走产品进行消费,若生产者没有生产产品,则消费者无法进行消费)
注意:区分互斥与同步只需记住,只要是同类进程即为互斥关系,不同类进程即为同步关系
(2)临界资源与临界区
进程在运行过程中,一般与其他进程共享资源,而有些资源的使用具有排他性。我们把同时仅允许一个进程使用的资源称为临界资源,如打印机、绘图机等
为了保证临界资源的正确使用,可以把临界资源的访问过程分为四部分。这四部分都属于要访问临界资源的进程,是进程中的一部分代码
进入区:为了进入临界区使用临界资源,在进入区要检查是否可以进入临界区;如果可以进入临界区,同行设置相应的“正在访问临界区”的标志,以阻止其他进程同时进入临界区
临界区:进程中用于访问临界资源的代码,又称临界段
退出区:临界区后用于将“正在访问临界区”标志清除的部分
剩余区:进程中除上述3部分以外的其他部分:
两个容易混淆的概念:有人可能认为临界区就是临界资源的所在地址,这样理解显然是错误的。简单一些说,临界资源是一种系统资源,需要不同进程互斥访问,而临界区则是每个进程中访问临界资源的一段代码,是属于对应进程的,临界区前后需要设置进入区和退出区进行检查和恢复,临界区和临界资源是不同的,临界资源是必须互斥访问的资源,这种资源同时只能被一个进程所使用,但需要这种资源的进程不止一个,因此需要对使用临界资源的进程进行管理,这也就产生了临界区的概念
这里还要弄清楚一个概念:每个进程的临界区代码可以不相同。临界区代码由于要访问临界资源,因此要再进入临界区之前(也就是执行临界区代码之前)进行检查,至于每个进程对临界资源进行怎样的操作,A要写磁盘的前半部分,B要读磁盘的后半部分。这两个进程对磁带操作的部分那就是两个进程各自的临界区,不能同时执行,但内容是不相同的,不可认为临界资源相同,访问这些资源的代码也是相同的
(3)互斥的概念与要求
根据互斥的定义,当一个进程进入临界区使用临界资源时,另一个进程必须等待,知道占用该临界资源的进程退出临界区时,才允许访问该临界资源。为了禁止两个进程同时进入临界区,软件算法或同步机构都应遵循以下的规则:
空闲让进:当没有进程处于临界区时,可以允许一个请求进入临界区的进程立即进入自己的临界区
忙则等待:当已有进程进入其临界区时,其他进入临界区的进程必须等待
有限等待:对要求访问临界资源的进程,应保证能在有限的时间内进入自己的临界区
让权等待:当一个进程因为某些原因不能进入自己的临界区时,应释放处理器给其他进程
(4)同步的概念与实现机制
一般来说,一个进程对另一个进程的运行速度是不确定的。也就是说,进程之间实在异步环境下运行的。但是相互合作的进程需要在某些确定的点上协调他们的工作。所谓进程同步,是指多个相互合作的进程在一些关键点上可能需要互相等待或互相交换信息,这些相互制约的关系称为进程同步,可以用信号量实现同步。