进程管理
1. 进程与线程
1.1 进程
为什么引入进程?
- 程序的并发执行特征
- 间断性
- 失去封闭性
- 不可再现性
- 程序并发执行时产生的不可再现性,决定了通常的程序不能参与并发执行
- 为了使程序能够正确地并发执行,操作系统中引入了进程的概念,用进程来表示一个并发执行的程序
进程的定义
- 进程是代码在数据集合上的一次运行活动,是资源分配的基本单位
- 为了描述和控制进程,OS必须为每个进程建立一个进程控制块PCB(Process Control Block)。
- PCB、程序段和相关的数据段构成一个进程实体(又称进程映象),简称进程
1.2 线程
为什么引入线程?
- 进程是资源的拥有者,进程在创建、撤销和切换中,系统的时空开销大
- 引入线程减少程序并发执行时所付出的时空开销,使OS具有更好的并发性
- 线程切换时只需保存和设置少量寄存器内容,代价远低于进程
线程的定义
- 线程由线程标识符、程序计数器、一组寄存器的值和堆栈组成
线程的特征
- 线程是CPU调度和分派的基本单位
- 线程基本不拥有系统资源
- 线程和同一个进程的其他线程共享进程的全部资源
线程的创建和终止
- OS为应用程序创建一个进程,同时为该进程创建第一个线程
- 以后的线程是由线程创建的,但线程间并不提供父子关系的支持
- 线程完成自己的工作或运行中出现错误或其他原因会终止
线程的实现
- 内核支持线程KST(Kernel Supported Threads)
- 用户级线程ULT(Uesr Level Threads)
- 组合方式
1.3 区别
调度性
- 线程是调度和分派的基本单位,是独立运行的基本单位。
- 同一进程中线程的切换不会引起进程的切换,但从一个进程的线程切换到另一个进程的线程时会引起进程的切换
并发性
- 进程之间可以并发实行,一个进程中的多个线程也可以并发执行,使得OS具有更好的并发性
拥有资源
- 进程是资源分配的基本单位,线程本身不拥有系统资源,仅有一点必不可少能保证独立运行的资源(如线程控制块TCB、程序计数器、寄存器和堆栈)
- 多个线程可共享所属进程的所有资源
独立性
- 同一进程中的不同线程的独立性比不同进程之间的独立性低。因为防止进程之间彼此干扰和破坏,每个进程都拥有一个独立的地址空间和其他资源
系统开销
- 由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,所付出的开销远大于创建或撤销线程时的开销。类似地,在进行进程切换时,涉及当前执行进程 CPU 环境的保存及新调度进程 CPU 环境的设置,而线程切换时只需保存和设置少量寄存器内容,开销很小。
通信方面
- 线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助 IPC
2. 进程的状态
进程的基本状态
- 就绪状态。获得除CPU外的所有资源,得到CPU便可立即执行
- 执行状态。
- 阻塞状态。正在执行的进程因某种事件(如I/O请求)发生暂时无法继续执行
进程的状态转换
注意
- 只有就绪态和运行态可以相互转换,其它的都是单向转换。
- 阻塞状态是缺少需要的资源从而由运行状态转换而来,但是该资源不包括 CPU 时间,缺少 CPU 时间会从运行态转换为就绪态。
3. 进程控制块
- 为了描述和控制进程的运行,系统为每个进程定义了一个数据结构—进程控制块,即PCB。
- PCB的作用是将程序变成可并发执行的进程,系统根据进程的PCB感知到进程的存在,并通过PCB对进程进行控制,因此PCB是进程存在的唯一标志。
进程控制块包含的信息
- 进程标识符
- 处理机状态
- 进程调度信息
- 进程控制信息
4. 进程控制
操作系统内核
现代操作系统一般将OS划分为若干层次,再将OS的不同功能分别设置在不同的层次中。
通常将一些与硬件相关的模块、各种常用设备的驱动程序、运行频率较高的模块,安排在仅靠硬件的软件层次中,将它们常驻内存,这部分被称为OS内核。
- 为了使操作系统内核代码和数据不会遭受到用户程序的破坏,通常将处理机的状态分为
(1)系统态,也叫管态或内核态。
(2)用户态,也叫目态。
通常,操作系统内核运行在系统态,用户程序运行子啊用户态
原语是指由若干条指令组成、用来实现某个特定操作的一个过程。原语的执行具有原子性,即原语在执行过程中不允许被中断。原语常驻内存,且在系统态下执行。
进程的创建与终止
- 创建进程使通过创建原语完成的,进程创建原语的主要任务是创建进程控制块PCB
- 终止进程的实质是收回PCB
5. 进程同步
5.1 进程同步
进程同步概念
- 进程同步是指对多个相关进程在执行次序上进行协调,使系统中诸进程之间能按照一定的时序或规则,共享资源和相互合作,从而使程序的执行具有可再现性。
- 用来实现同步的机制被称作同步机制
两种形式的制约关系
- 间接相互制约。这种制约主要源于资源共享
- 直接相互制约。这种制约主要源于进程合作
5.2 同步与互斥
- 同步:多个进程因为合作产生的直接制约关系,使得进程有一定的先后执行关系。
- 互斥:多个进程在同一时刻只有一个进程能进入临界区。
5.3 临界资源和临界区
- 临界资源:一次只能允许一个进程使用的资源,如打印机、共享变量等
- 临界区:访问临界资源的那段代码称作临界区
- 进入区:在临界区前用来检查对应的临界资源是否正在被其他进程访问的代码
- 退出区:在临界区后用于将临界区从正被访问的标志恢复为未被访问的标志
5.4 同步机制应遵循的规则
- 空闲让进。临界资源空闲时允许一个请求进入临界区的进程立即进入自己的临界区
- 忙则等待。临界资源正被访问时,其他要求进入临界区的进程必须等待,以保证对临界资源的互斥使用
- 有限等待。任何要求访问临界资源的进程应该能在有限的时间内进入自己的临界区
- 让权等待。不能进入临界区的进程应立即释放CPU
5.5 信号量机制
整型信号量
- 一个整型信号量对应与一类临界资源,非负的共享整数,用来表示该类资源的数目。通过两个原子操作wait(也称作P)和signal(也称作V)来访问。
- wait操作表示申请一个资源,signal操作表示释放一个资源
- 存在问题:主要S <= 0,wait操作就会不断测试,因而整型信号没有遵循“让权等待”的规则
记录型信号量
- 记录型信号量除了用于代表资源数目的整型变量外,还增加一个进程链表指针,用于链接所有等待该资源的进程
- 记录型信号量遵循了“让权等待”规则
信号量的应用
- 利用信号量实现前驱关系
- 利用信号量实现互斥。为某个资源设置一互斥量mutex,多个进程就能互斥的访问该临界资源
5.6 管程(Monitors)机制
为什么引入管程
- 信号量机制中大量的同步操作分散在各个进程中,给系统的管理带来麻烦,而且会因同步操作的使用不当导致系统死锁
管程的定义
- 管程是由一组局部的共享变量、对局部变量进行操作的一组过程以及对局部变量进行初始化的语句序列构成的一个软件模块。
管程实现互斥
- 所有进程要访问临界资源只能通过管程间接访问,而且管程每次只允许一个进程进入管程,执行管程的过程,从而实现了进程互斥。
管程实现同步
- 引入条件变量和相关的wait、signal操作
- wait操作。如 x.wait() 用来执行将进程挂到与条件变量x相应的等待队列上
- signal操作。如 x.signal() 用来唤醒与x条件变量相应的等待队列上的一个进程
6. 经典同步问题
6.1 生产者-消费者问题
6.2 哲学家进餐问题
6.3 读者-写者问题
7. 进程通信
- 进程通信是指进程之间的信息交换
进程通信的类型
- 高级通信是指用户直接利用操作系统所提供的一组通信命令(原语),高效地传送大量数据地一种通信方式
(1)共享存储器系统
- 在内存中划出一块共享存储区域,诸进程可通过对该共享区地读写交换信息,实现通信
(2)管道通信
- 管道,是指用于连接一个读进程和一个写进程以实现它们之间通信地一个共享文件
- 管道机制必须提供三方面地协调能力:①互斥 ②同步 ③确定对方是否存在
(3)消息传递系统
- 进程不必借助任何共享存储区或数据结构,而是以格式化地消息为单位,将通信的数据封装在消息中,并利用操作系统提供的一组通信命令(原语),在进程间进行消息传递
(4)客户机-服务器系统
-
套接字
-
远程过程调用和远程方法调用
消息传递通信的实现方式
- 直接通信
- 间接通信
消息缓冲队列通信机制
- 消息缓冲队列通信机制通过内存中公用的消息缓冲区进行进程通信,属于直接通信方式
发送进程发送消息时,需申请一个消息缓冲区,并把自己的进程标识符和有关消息的内容填入消息缓冲区,然后将该消息缓冲区插入到接收进程的消息缓冲队列中;接收进程接收消息时,需从自己的消息缓冲队列中摘下一个消息缓冲区,取出其中的消息,然后把消息缓冲区归还给系统。