操作系统进程管理

进程

概念

程序是静态代码块,进程是程序的一次执行过程,是动态的,一个程序可以创建多个进程。

操作系统使用进程id即PID区分进程,该字段保存在PCB进程控制块中,其中还有用户id-UID、分配的资源,运行情况等信息,PCB是进程存在的唯一标志;此外进程还由程序段和数据段构成,程序段读入内存由cpu执行,数据段存放运行过程中产生的各种数据。

进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位,相同程序的多个进程,其PCB和数据段不同,程序段相同。

特征

动态性、并发性、独立性、异步性、结构性

状态及状态转换

创建态,分配资源,初始化PCB
就绪态,进程具备运行条件,但无空闲cpu,暂时不能运行
运行态,正在cpu上运行的进程
阻塞态,等待其他资源或进程,该进程需要下cpu,等待条件满足恢复为就绪态
终止态,执行完成或出现不可修复的错误,使用exit系统调用请求操作系统终止该进程,回收资源

大致流程为:
创建态——就绪态——运行态(——阻塞态—>就绪态)——终止态

进程通信

各进程间内存地址空间相互独立且不可访问其他地址,为实现多个进程产生数据交互,需要操作系统支持实现进程通信IPC,实现方法有三种:

共享存储

通过一块共享存储区交换数据,多个进程共享该存储区,都可以读写,但未了保证数据安全,防止覆写,需要保证进程间访问互斥,通过操作系统的同步互斥工具实现,如PV原语。

消息传递

数据以格式化消息为单位,通过操作系统提供的发送/接受消息原语交换,消息一般由消息头和消息体构成,消息头包含发送进程ID、接受进程ID,消息长度等格式。

具体可分为直接通信和间接通信,直接通信指发送时指明接受进程的ID,消息进入内核空间形成消息队列,接受时检查消息队列,找到要接受的消息;间接通信通过信箱实现,发送放不指定接受进程,直接将消息发送到信箱,接受也只从特定信箱接收。

管道通信

一端写入,一端读取,消息单向流动,管道实质是一个特殊的共享文件pipe,本质就是在内存中开辟一个大小固定的缓冲区,与共享存储类似,但限制更多,消息先进先出,访问互斥由操作系统实现。

当管道写满时,写进程阻塞,管道读空时,读进程阻塞,数据一经读出彻底消失,多进程读同一管道可能发生错乱,可以限制读取进程只能有一个,或多个进程轮流读取。

组织方式

根据PCB的state标识状态组织进程。

链接方式

执行指针,就绪队列指针,阻塞队列指针构成的链表,阻塞队列指针可根据原因不同划分多个阻塞队列。

索引方式

state使用索引方式链接。

进程控制

通过原语实现进程状态转换,原语是一种特殊指令,执行具有原子性,执行过程一气呵成不可中断,避免关键数据的不统一。

原子性的实现通过关中断和开中断两条特殊指令实现,执行关中断指令后不再检查外部中断信号,直到开中断指令执行后,在每条指令后检查中断信号。

创建原语,申请空白PCB,为新进程分配所需的资源,初始化PCB,将PCB插入就绪队列。

撤销原语,PCB集合中找到对应PCB,如果正在运行则将CPU分配给其他进程,终止所有子进程,将该进程拥有的所有资源归还给父进程或操作系统,然后删除PCB。

阻塞原语,找到对应PCB,保护进程运行现场,将state设置为阻塞态,暂时停止,将PCB插入相应事件的等待队列。

唤醒原语,找到PCB,从等待队列移除,设置为就绪态,将PCB插入就绪队列。

切换原语,当前进程的运行环境信息存入PCB,并移入相应队列,执行进程更新PCB,根据PCB恢复进程所需的运行环境。

线程

概念

一个进程内的多个功能要同时实现,比如微信的聊天,视频,文件发送功能,所以引入线程增加并发度,引入的线程是程序执行流的最小单位。实质是轻量级的进程,线程是基本的cpu执行单元,是程序执行流的最小单位。

线程也有线程ID,线程控制块TCB,有就绪,阻塞,运行,三种基本状态。线程几乎不拥有系统资源,同一进程下的不同线程间共享进程资源,通信无需系统干预,线程切换不引起进程切换,且开销较小。

实现方式

用户级线程

通过线程库实现,多用在早期不支持线程的操作系统上,最简单的实现方式是在while循环中分别依次处理不同业务,是逻辑上的线程。

该方法不需要切换到核心态,线程管理系统开销小,效率高,但一个线程阻塞整个进程阻塞,并发度低,多个线程不可在多核处理机上并发运行。

内核级线程

操作系统完成线程管理,线程切换需转换状态,并发性强,可在多核处理机上并发执行,切换管理成本高,开销大。

多线程模型

用户级线程和内核级线程对应关系分别为:
一对一,并发性强,管理成本高,开销大;
多对一,开销小效率高,只有内核级线程才是处理机分配的单位;
多对多,克服并发度不高和开销大的缺点。

线程状态转换

与进程一致,组织控制通过TCB线程控制块实现,与进程相同。

处理机调度

分类

高级/作业调度,从外存的作业后备队列中选一个放入内存,创建进程,每个作业只调入一次,调出一次,调入时建立PCB,调出时撤销PCB。

低级/进程/处理机调度,从就绪队列中选择一个分配给处理机。

中级/内存调度,内存不够时需要将进程数据调出外存,将挂起的PCB组成挂起队列,该调度方法决定如何将挂起进程重新调入内存。

调度时机

当前进程主动或被迫放弃处理机时,但在中断处理过程中、进程在操作系统内核程序临界区中、和原语中不能进行。

放弃处理机有两个方法,非抢占式是指允许进程主动放弃处理机,抢占式是有更重要的进程时直接抢占处理机。

调度过程

用调度算法决定让谁运行,时间片大小决定一个进程运行多久,当无其他就绪进程时自动调入闲逛进程,该进程优先级最低,指令周期末尾检查中断,能耗低。

调度算法评价标准

cpu利用率,我们希望cpu尽可能多地工作,计算方法为工作时间/总时间

系统吞吐量,单位时间内完成的作业数量,作业数量/时间

周转时间,作业提交到系统完成的时间间隔
平均周转时间,周转时间之和/作业数
带权周转时间,周转时间/实际运行时间

等待时间,等待处理机的时间之和,由调度算法决定

响应时间,提交请求到首次响应所用时间

调度算法

先来先服务FCFS

公平,算法实现简单,对长作业有利,短作业不利,不会产生作业长时间得不到服务的饥饿问题。

短作业优先SJF

追求最少的平均等待时间,平均周转时间和平均带权周转时间,最短的作业优先得到服务,非抢占式在每次调度选择当时已到达且运行时间最短的进程;抢占式在每次进程加入就绪队列和进程完成时调度,计算最短剩余时间,也叫最短剩余时间优先。

该算法平均等待时间,平均周转时间最少,但不公平,短作业有利,长作业不利,可能产生饥饿,且运行时间由用户提供,不真实,可能造假。

高响应比优先HRRV

兼顾等待时间和运行时间,调度时计算作业的响应比,

计算方法为:相应比=(等待时间+响应时间)/要求服务时间

每次调度选择最高的作业服务,该算法下等待时间相同,要求服务时间短的优先,要求服务时间相同时,等待时间长的优先,作业不会发生饥饿

总结一

上述算法主要关心公平性和系统整体性能,不关心响应时间,也不区分任务紧急程度,没有交互性,主要应用于早期批处理操作系统

时间片轮转RR

公平,轮流为各进程服务,轮流执行一个时间片,时间片结束未执行完则剥夺处理机,将进程重新放到就绪队列尾排队,更注重响应时间,不计算周转时间。

时间片太大退化为先来先服务,太小则过于频繁切换进程,开销太大,一般设计为进程切换占比性能你不超过1%,该算法解决交互性,但不能区分任务紧急程度。

优先级调度

调度时选择优先级最高的作业,抢占式非抢占式都有,就绪队列可以根据优先级组织,优先级可静态设定,也可动态改变,静态设定通常系统高于用户,前台高于后台,操作系统相对计算型进程更偏好I/O进程,因为输入输出设备与cpu可并行工作,先执行io进程可以提高资源利用率和系统吞吐量;动态调整可以根据等待时间,等待时间长的适当提升优先级,运行时间久的适当降低优先级。

该算法可能导致饥饿,一直有高优先级进程进入,低优先级可能饿死。

多级反馈队列调度

是各个调度算法的折中选择,设置多级就绪队列,优先级从高到底排列,可使用的时间片从小到大,即优先级高的先执行,但能执行的时间片小。

新进程进第一级队列,时间片用完进入下一级的队尾,依次执行,已经在最下级的重新放到最下级的队尾,k级为空才给k+1级对头进程分配时间片。

该算法各类进程相对公平,响应快,短进程用较少时间完成,避免用户作假运行时间,可灵活调整各类进程的偏好程度,可能产生饥饿。

多级队列调度

设置多个就绪队列,比如按进程类型分别设置系统进程、交互式进程、批处理进程,优先级从高到低,可设置固定优先级或根据时间片划分,各队列采用不同调度策略。

进程的同步互斥

进程的执行具有异步性,协调进程执行的工作次序为同步;
一个时间段只允许一个进程使用的资源是临界资源,进程对临界资源的访问需要互斥进行。

互斥访问的逻辑为:
进入区,检查访问标志
临界区,访问临界资源
退出区,接触访问标志
剩余区,其他处理

为保证系统性能,互斥访问应遵循以下特性:
空闲让进,有限等待,忙则等待,让权等待(不能进入临界区的进程立即释放处理机)

互斥的软件实现方法

单标志法

进程访问完临界资源后,把权限转给另一个进程,每个进程进入临界区的权限只能被另一个进程赋予。
该方法可实现同一时刻最多只能允许一个进程访问临界区,但使用只能交替进行,违反了空闲让进原则。

双标志先检查法

设置数组标志进程是否想进入临界区,如果对方不想用而自己想用则进入,退出时将自己设置为不想用。
该方法在并发执行下无法保证互斥,原因在于检查和上锁非一气呵成,前后执行可能发生进程切换,违反了忙则等待原则。

双标志后检查法

即先上锁,再检查,解决了忙则等待问题,但二者可能都上锁而等待对方,产生死锁一直等待,违反空闲让进和有限等待原则。

Peterson算法

结合双标志法,双方都想进入时谦让对方,使用数组表达进入意愿,也使用turn表达谦让,检查对方意愿和谦让,如果对方不用且对方谦让时才进入临界区,在使用后的结束区将自己的意愿设为否。

主动争取,主动谦让,检查对方是否想使用,二者如果都想使用,谁在最后说了客气话就失去了行动优先权。

该算法仍未实现让权等待原则,仍是不断检查等待,未释放处理机资源。

硬件实现互斥

中断屏蔽法

使用开/关中断指令实现,简单高效,但不适用于多处理机,因为开关中断指令只对本处理机适用,且不适用于用户进程。

TS指令

TestAndSet或TestAndSetLock,通过在临界区上锁硬件实现不被中断,硬件上锁一气呵成,实现简单,适用于多处理机环境,但不能满足让全等待原则,处理机仍出于忙等待。

Swap指令

与TS指令相同,只是通过交换锁的方式来检查临界区是否有锁。

信号量机制—PV操作

上述所有方法均不能实现让权等待,即等待资源无法获得时让出虚拟机,故dijkstra提出了信号量机制,即用原语对信号量进行操作,实现进程的同步互斥,信号量就是一个变量,用于表示某种资源的数量。

PV操作

使用wait(s)signal(s)原语,实现对资源s的访问和退出,简化为P(s)V(s)操作,信号量又可分为两种,整型和记录型信号量。

整型信号量是用整数表示资源数量,只有初始化、p、v三种操作,wait原语检查资源是否足够,不够就循环等待,直到资源可用再占用资源,signal原语在退出去释放资源;其实与双标志先检查法一直,只是使用了原语操作,执行一气呵成,但仍不满足让权等待。

记录型信号量是用记录型数据结构表示的信号量,由剩余资源数和等待队列构成,wait过程中剩余资源数value-1,若资源数小于0使进程进入阻塞态,挂到信号量的等待队列block中;signal操作执行剩余资源数value+1,若仍然小于0说明有别的进程在等待该资源,使用wakeup原语唤醒等待队列中的一个进程,由阻塞态变为就绪态,满足让权等待,不会忙等。

实现进程互斥

1,划定临界区
2,设置互斥信号量mutex,初始值为1
3,进入区申请资源,p(mutex)加锁
4,临界区代码
5,退出区释放资源,v(mutex)

其中不同资源需要设置不同的互斥信号量

实现进程同步

1,确定同步前后关系
2,设置同步信号量,初始值为0
3,p1进程执行后使用v操作释放资源
4,p2进程申请资源,实现p1,p2先后执行

哲学家进餐问题

五个哲学家除了思考就是吃饭,五根筷子依次拿起,左右两个筷子,筷子如果有一根在他人手上,需要等待,五个哲学家对中间的筷子互斥访问。

信号量设置为数组,chopsticks[5]={1,1,1,1,1};哲学家左手编号为i,右手编号为(i+1)%5,拿起是先拿左再拿右,v释放,两个人并发拿一根筷子,可能产生死锁,互相等待。

为了防止等待,可用在哲学家拿筷子前加以限制,比如:
奇数号哲学家先拿左手边的筷子,偶数的拿右手边的筷子,使二者争抢,只有一个人能拿到筷子
仅有左右筷子都可用的时候才能开始拿筷子

管程

使用信号量编写程序困难,易出错,基于封装设计一种机制,让程序员不再关注pv操作,是一种高级互斥同步机制,构成为:
1,局部于管程的共享数据结构
2,对数据结构进行操作的一组过程
3,对局部于管程的共享数据设置初始值的语句
4,管程名

基本特征为:
管程数据结构与过程的私有性
每次只有一个进程在管程内执行某个内部过程

管程的互斥特点由编译器实现,比如在java中使用synchronized描述的函数,同一时间段只能被一个线程调用。

死锁

并发环境下,进程互相等待对方手里的资源,导致进程阻塞,无法进行,至少有两个以上进程同时发生。

与饥饿和死循环相区别:
饥饿,进程长期得不到想要的资源,可能只有一个
死循环,执行过程中一直跳不出某种循环,上面两个问题是管理者操作系统的问题,该问题则是被管理者的问题

死锁产生的条件

互斥,对互斥资源争抢导致死锁
不剥夺,资源未使用完时不能强行夺走,只能主动释放
请求和保持,进程已保持了至少一个资源,又提出了新请求
循环等待,存在进程资源的循环等待链,但有循环等待未必死锁,有需要的资源在循环外时就不锁

总之死锁就是不可剥夺的资源分配不合理产生的。

死锁的处理

预防

预防是要破坏死锁产生的条件。

破坏互斥,把只能互斥使用的资源逻辑上改造成共享设备,比如SPOOLING技术,请求由输出进程接收,进程继续向下执行,请求被暂时保管,但很多时候必须要保证互斥条件,无法破坏互斥条件。

破坏剥夺条件,优先级抢占,实现复杂,强制剥夺造成之前的工作失效,只适用于易保存和恢复状态的资源,反复申请释放资源也增加系统开销,可能导致饥饿。

破坏请求和保持条件,静态分配,一次性申请全部资源,未满足前不投入运行,实现简单,但进程运行要一直保持所有资源,利用率低,可能导致饥饿。

破坏循环等待,顺序资源分配法,给资源编号,进程必须按编号递增的顺序请求资源,不方便新增设备,因为需要重新编号;实际使用资源顺序与递增顺序不一致时会导致资源浪费,必须按规定申请资源,用户编程麻烦。

避免

设置安全序列,系统按照该系列分配资源,保证每个进程都能顺利完成,此时系统为安全状态,不安全状态就可能发生死锁。
Dijlstra发明的银行家算法,本来是为了确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。就算再分配资源前,判断这次分配是否会导致系统进入不安全状态,会则阻塞进程。

1,检查此次申请是否超过之前声明的最大需求数
2,检查此时系统剩余的可用资源是否能满足此次请求
3,试探分配更改个数据结构
4,用安全性算法检查此次分配是否会导致系统进入不安全状态。

安全性算法是,检查当前剩余可用资源是否能满足某个进程的最大需求,若可以,则加入该进程到安全序列,不断重复,看最后能否让所有进程加入到安全序列中。

检测和解除

借助图这一数据结构,具体由进程和资源节点,请求和响应边组成。

检测算法为依次消除与不阻塞进程相连的边,即分配得到满足的进程消除其边,最后剩余的是阻塞进程,若能完全消除,则无死锁。

解除方法如下:
资源剥夺法,将进程挂到外存,资源转给其他进程,需要防止挂起进程饥饿。
撤销进程法,撤销部分死锁进程,剥夺资源,代价大,进程需要重新执行。
进程回退法,让一个或多个死锁进程回退到足以避免死锁,要记录进程历史信息,设置还原点。

具体解除方法可根据优先级,执行时间,剩余完成事件,已用资源等选择不同策略。

总结

本章介绍了操作系统管理进程的方法,从进程通信,组织方式开始,着重介绍了处理机调度进程的算法,以及在多处理机下如何实现进程的同步互斥,及防止死锁的方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值