操作系统五大功能之进程管理

一.进程实体

1.1 为什么需要进程

在没有配置OS之前,资源只属于当前运行的程序,计算机只能运行一个程序,而且是一个程序接着一个程序运行,所以资源无法合理利用。
配置OS之后,引入多道程序设计的概念。
进程随之出现,进程合理隔离资源、运行环境,提升资源利用率。

  • 进程是系统进行资源分配和调度的基本单位
    有了多道程序设计的概念,操作系统就可对资源进行分配,进程是其基本单位。
  • 进程作为程序独立运行的载体保障程序正常执行
    有了多道程序设计的概念,就会有多个进程共同使用同一个物理设备,进程就起到隔离资源的作用。
  • 进程的存在使得操作系统资源的利用率大幅提升
    也是依赖于多道程序设计这个设计概念

1.2 进程实体

1.2.1 主存中的进程形态

在主存中,进程也是一段连续的空间,称之为进程控制块。进程控制块包含了很多重要信息。如下:

  • 标识符:标识符唯一,标记一个进程,用于区别其他进程。常说的进程ID。
  • 状态:标记进程的进程状态。如:运行态、阻塞态。
  • 程序计数器:指向进程即将执行下一条指令的地址。
  • 内存指针:程序代码、进程数据相关指针。
  • 上下文数据:进程执行时处理器存储的数据。
  • IO状态信息:被进程IO操作所占用的文件列表。
  • 记账信息:使用处理器时间、时钟数总和等
  • ……

上述信息总结一下就是:进程标识符、处理机状态、进程调度信息、进程控制信息

进程控制块(PCB):用于描述和控制进程运行的通用数据结构,记录进程当前状态和控制进程运行的全部信息。PCB使得进程是能够独立运行的基本单位,每一个进程都依赖PCB被操作系统调度控制。PCB是操作系统进行调度经常会被读取的信息,所以PCB是常驻内存的,存放在系统专门开辟的PCB区域内。

1.2.2 进程与线程

一个进程可以有一个或多个线程。

进程(Process)线程(Thread)分析
进程是操作系统进行资源分配和调度的基本单位线程是操作系统进行运行调度的最小单位操作系统对进程的调度实际上是对进程中的线程进行调度
一个进程可以并发多个线程,每个线程执行不同的任务线程包含在进程之中,是进程中实际运行工作的单位
进程拥有资源线程不拥有资源而是共享进程的资源资源方面
系统开销大系统开销小系统开销方面
进程间通信IPC读写同一个进程数据通信通信

进程-线程示意图

二.状态模型

进程在操作系统中有个状态:创建、就绪、阻塞、执行和终止。

  • 就绪状态:
    当进程被分配到除CPU以外所有必要的资源后,只要再获得CPU的使用权,就可以立即运行。其他资源(PCB、内存、栈空间、堆空间)都准备好、只差CPU资源的状态为就绪状态。
    在操作系统中是可以有多个进程并发运行的,因此可能存在多个就绪进程,在一个系统中多个处于就绪状态的进程通常排成一个队列。
  • 执行状态:
    进程获得CPU,其程序正在执行称为执行状态。在单处理机中,在某个时刻只能有一个进程是处于执行状态。
  • 阻塞状态:
    进程因某种原因(如:其他设备未就绪)而无法继续执行,从而放弃CPU的状态称为阻塞状态。同样也有阻塞队列,定义与就绪队列相似。
  • 创建状态:
    创建进程首先要分配PCB,所创建进程时拥有PCB其他资源尚未就绪的状态称为创建状态。
  • 终止状态:
    进程结束由系统清理或者归还PCB的状态成为终止状态。
    在这里插入图片描述

三.进程同步

3.1 为什么需要进程间的同步

3.1.1 生产者-消费者问题

有一群生产者进程在生产产品,并将这些产品提供给消费者进程进行消费,生产者进程和消费者进程可以并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程需要将所生产的产品放到一个缓冲区中,消费者进程可以从缓冲区取走产品消费。
问题思考
生产者生产产品放于缓冲池,缓冲区数量加一;消费者从缓冲池拿取产品,缓冲区数量减一。
缓冲区在Cache中,操作缓冲需要三个步骤:register=count;register=register±1;count=register。在了解以上情况后考虑下面这种情况:生产者生产一个产品,消费者消费一个产品,缓冲池产品数理应不变,但如下表却发生变化

registercount生产者-消费者实际执行代码顺序
1010register=count(生产者)
1110register=register+1(生产者)
1010register=count(消费者)
910register=register-1(消费者)
99count=register(消费者)
1111count=register(消费者)

缓冲池就是临界资源。(临界资源在3.2会给出定义)

3.1.2 哲学家进餐问题

有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共同使用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子。平时哲学家们只进行思考,饥饿时则试图取靠近他们的左、右两支筷子,只有两支筷子都被他拿到的时候就能进餐,进餐完毕之后,放下左右筷子继续思考。

问题思考
首先分析正常情况下,哲学家拿起左手筷子,发现右手筷子被拿了,则要等待右边筷子释放,释放后拿起右边筷子,进餐;其次考虑极端情况,五个哲学家同时拿起左手筷子,则右手筷子被拿起,五个哲学家都要等待右手筷子释放,相互等待最终都饿死。
筷子就是临界资源

3.1.3 总结

上面两个模型出现的问题的根源在于:彼此相互之间没有通信。“如果生产者通知消费者我已经完成一件生产”,“如果哲学家向旁边哲学家说我要进餐了”,那么就不会出现问题。

所以我们需要进程间的同步——“如果生产者通知消费者我已经完成一件生产”、“如果哲学家向旁边哲学家说我要进餐了”等。

进程间同步需要解决的问题:

  • 对竞争资源在多进程间进行使用次序的协调
  • 使得并发执行的多个进程之间可以有效使用资源和相互合作

3.2 进程间同步的原则

临界资源指的是一些虽作为共享资源却又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源时,其他进程必须依据操作系统的同步机制等待占用进程释放该共享资源才可重新竞争使用共享资源。
四个原则

  • 空闲让进:资源无占用,允许使用
  • 忙则等待:资源有占用,请求进程等待
  • 有限等待:在忙则等待的基础上,保证有限等待时间能够使用资源
  • 让权等待:等待时,进程需要让出CPU

3.3 进程同步的方法

  • 消息队列
  • 共享内存
    在某种程度上,多进程是共同使用物理内存的,由于操作系统的进程管理,进程间的内存空间是独立的,进程默认是不能访问进程空间之外的内存空间以此保证安全性。共享内存可以打破这个限制
    共享内存允许不相关的进程访问同一片物理内存,允许不相关的进程访问同一片物理内存。但是共享内存未提供同步机制,需要借助其他机制管理访问
    共享内存的步骤:申请共享内存——》连接到进程空间——》使用共享内存——》脱离进程空间并删除
  • 信号量
  • Unix域套接字
    域套接字是一种高级的进程间通信的方法,Unix域套接字可以用于同一机器进程间通信。套接字(socket)原是网络通信中使用的术语,Unix系统提供的域套接字提供了网络套接字类似的功能,如:可靠性。不需要借助其他机制帮助管理。

3.4 进程中的线程同步方法

3.4.1 各种方法

因为线程会并发使用进程中的资源,所以进程中的多线程也需要同步。同步方法如下:

  • 互斥量
    当某一线程操作临界资源时,互斥量可以阻止其他线程访问临界资源。生产者-消费者问题产生的原因就是生产者-消费者两个线程的指令交叉执行,而互斥量就可以保证两个线程的关键指令先后完整的执行,不会互相交叉,这一作用效果也叫原子性互斥量就是保证关键代码的原子性(原子性是指一系列操作不可被中断的特性,这一系列操作要么全部执行完成,要么全部没有执行,不存在部分执行部分未执行的情况)
    互斥量是最简单的线程同步的方法,互斥量(也叫互斥锁)是处于两态(解锁和加锁)之一的变量。两个状态可以保证资源访问的串行。比如:若一临界资源被加锁了,那么这一资源就是正在被某线程使用,其他线程就不可以使用了,解锁后,方可使用,以此保证串行。
  • 自旋锁
    工作原理与互斥量一模一样。
    自旋锁也是一种多线程同步的变量,使用自旋锁的线程会反复检查锁变量是否可用,自旋锁不会让出CPU,而是死循环等待锁被释放,是一种忙(则)等待状态。所以自旋锁避免了进程或线程上下文切换的开销,操作系统内部很多地方使用的是自旋锁;自旋锁不会让出CPU,所以不适合在单核CPU使用。
  • 读写锁
    工作原理与互斥量、自旋锁类似,并且做出一定改进。
    在实际的复杂开发环境中,临界资源可能出现多读少写(比如淘宝历史订单),读取的时候并不会改变临界资源的值,如果每次都加互斥锁或自旋锁,开销过大没有必要,因此需要更高效的读写锁。
    读写锁是一-种特殊的自旋锁,允许多个读者同时访问资源以提高读性能,对于写操作则是互斥的。
  • 条件变量
    条件变量是一种相对复杂的线程同步方法,条件变量允许线程睡眠,直到满足某种条件,当满足条件时,可以向该线程信号,通知唤醒。
    为了更好的说明条件变量,先完善一下生产者-消费者问题模型,补充两个约束条件:缓冲区小于等于0时,不允许消费者消费,消费者必须等待;缓冲区满时,不允许生产者往缓冲区生产,生产者必须等待。
    当缓冲区小于等于0且生产者生产一个产品时, 唤醒可能等待的消费者;当缓冲区满且消费者消费一个产品时,唤醒可能等待的生产者。这就需要使用条件变量。

3.4.2 线程同步方法总结

同步方法描述
互斥锁最简单的一种线程同步方法,会阻塞线程且让出CPU
自旋锁避免切换的一种线程同步方法,属于“忙等待”,不让CPU
读写锁为"读多写少”的资源设计的线程同步方法,特殊的自旋锁,可以显著提高性能
条件变量相对复杂的一一种线程同步方法,有更灵活的使用场景
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值