目录
0 引言
1 什么是进程
2 进程的状态
3 进程控制块PCB
4 如何执行进程的控制
5 线程
6 进程和线程的区别
7 上下文切换
8 进程调度算法
9 进程通信机制
10 死锁
0 引言 1 什么是进程
程序是完成特定任务的一段指令集合,进程就是我们程序的一次动态执行过程
2 进程的状态创建态
就绪态
运行态
阻塞态
就绪挂起态
阻塞挂起态
终结态
3 进程控制块PCB什么是PCB
在 *** 作系统中,用进程控制块,也就是PCB来描述进程的
PCB是进程存在的唯一标识
PCB中包含的信息
进程描述信息
进程标识符
用户标识符
进程控制和管理信息
进程所处的状态信息(new, ready, waiting, blocked, running等)
进程优先级
资源分配清单
有关内存地址空间或虚拟地址空间的信息,锁打开文件的列表和使用的IO设备信息
CPU相关信息
CPU中各个寄存器的值,当进程发生切换时,CPU的状态信息都会被保存在相应的PCB中,以便进程重新执行时,能够从断点处继续执行
PCB是如何组织的
通过链表的方式进行组织,把具有相同状态的进程链在一起,组成各种队列
4 如何执行进程的控制创建进程
为进程分配一个唯一的进程标识号,并申请一个空白的PCB,PCB是有限的,若PCB申请失败则进程创建失败
为进程分配资源,若资源不足,则进程就会进入等待状态,加入等待队列
初始化PCB
如果进程的调度队列任仍然可以容纳新进程,那么就将进程插入到就绪队列,等待被调度运行
终止进程
查找要终止进程的PCB
若进程出入执行状态,则将其立即停止,并将CPU资源分配给其他进程
查看当前进程是否有子进程,有子进程则一起终止
将进程拥有的资源返还给父进程或CPU
将进程从所在的PCB队列中移除
阻塞进程
查到要阻塞进程的PCB
如该进程处于运行状态,则保护现场后将其状态改变为阻塞状态
将该进程挂到阻塞队列上
唤醒进程
在该进程等待的阻塞队列中找到对应的PCB
将进程从阻塞队列中移除,并改变其状态为就绪态
将该进程加入到就绪队列中
5 线程线程是程序的一个执行流程,同一个进程的线程之间共享代码段,数据段,页表等资源,每个线程又有自己独自的寄存器和栈,这样就确保了线程的控制流是相互独立的。
线程又分为两类,分别是用户线程和内核线程,用户线程是基于用户空间的线程库实现的,需要自己实现线程调度和管理,内核线程是由 *** 作系统内核来创建的,可以交由 *** 作系统来完成线程的调度和管理
6 进程和线程的区别进程是我们资源分配的单位,线程是我们CPU进程调度的基本单位
进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈
线程能够减少并发执行的时间和空间开销
线程的创建需要的资源少,可以直接共享进程的相关资源
线程终结更快,需要释放的资源更少
同一个进程内的线程切换更快,因为线程之间可以共享进程的虚拟内存,也就是页表,这样线程切换就没必要再加载页表信息
7 上下文切换上下文切换分为CPU上下文切换,进程上下文切换和线程上下文切换,切换的上下文如下:
首先来看一下CPU上下文切换要保存哪些上下文
CPU上下文就是CPU寄存器和程序计数器的信息
进程上下文切换
进程上下文切换包括虚拟内存,栈,全局变量等用户空间的资源,还包括内核堆栈,寄存器等内核空间的资源
线程上下文切换
若线程属于不同的进程,则与进程上下文切换是一样的
若线程属于同一进程,则线程上下文切换只需要切换自己的私有资源,如自己的栈和寄存器。
8 进程调度算法先来先服务算法
每次从就绪队列中取出最先到达就绪队列的进程进行CPU的分配,只有当该进程执行完毕或者被阻塞才会进行下一个线程的调度
该算法虽然公平但是对于短作业不利
最短作业优先算法
每次就绪队列中取出执行时间最短的进程进行调度,能够提高响应时间,但是对大作业不利,甚至可能出现大作业饿死的极端情况
高响应比优先算法
响应比=(等待时间+需要执行时间)/ 需要执行时间;具有高响应比的进行优先被调度,该算法兼顾了长作业与短作业。对于短作业,需要执行的时间段,响应比也就大,月容易被调度;对于长作业,等待的时间长了以后响应比也会增大,从而被调度而不至于出现饿死的状况
时间片轮转算法
每个执行的进程都有一个同一的CPU时间片分配,进程被调度后,最多能执行改时间片长度的时间,时间片时间到了或者进程被其他进程中断后就会调度就绪队列中的下一个线程,原进程若还没执行完,则放到就绪队列末端排队等待下一次的调度
最高优先级优先算法
每个进程都有优先级,这个优先级可以是静态的也可以是动态的,优先级高的优先被调度。该算法也分为抢占式和非抢占式,抢占式时队列中存在比当前运行进程优先级高的进程时中断正在运行的进程后调度优先级高的进程;非抢占式是即使队列中有高优先级的线程也得等待当前正在使用CPU的线程执行完后再进行调度
多级反馈优先队列算法
假设有1-n共n个调度队列,则队列优先级从1-n逐渐减小,调度队列的分配的时间片从1-n以此增大。调度规则如下:
新任务先放入第一级调度队列,执行完后下放到第二级调度队列,以此类推
低优先级调度队列中的任务只有在高优先级调度队列中没有任务的时候才有可能被调度
低优先级调度队列的任务在执行时若高优先级调度队列中有任务入队则立刻终止任务的执行并将任务放到原队列的末端,然后执行高优先级调度队列中的任务
9 进程通信机制管道通信
匿名管道
通信范围是存在父子关系的进程,因为管道没有实体,也就没有管道文件,只能通过fork()来复制父进程的fd文件描述符来达到通信的目的
命令管道
可以在不相关的进程之间通信,通过管道命令可以创建一个类型为管道的设备文件,在进程里只要使用这个设备文件就可以相互通信
不管匿名管道还是命名管道,进程写入的数据都是在 *** 作系统内核的缓存中,另一个进程自然也得从内核中去,同时通信数据都遵从先入先出的原则。
消息队列
通信方式
A进程要和B进程通信,A进程向消息队列中存放数据,然后就可以直接返回,之后B进程再从消息队列中读取数据即可
数据结构
消息队列是存在于内核中的一条链表,链表的节点时一个个固定大小的消息体,当进程从消息队列中读取一个消息体后就会将该消息体从消息队列中移除
存在的问题
通信不及时,消息体有大小限制,不适合比较大的数据传输
共享内存
我们的进程都有自己的虚拟地址空间,不同进程虚拟地址空间可以映射到不同的物理内存上。我们可以在通信双方的虚拟内存中拿出一部分映射到同一块物理内存上,这样两个进程写入到这片内存的数据就能立马被对方看到,这样就避免了用户态和内核态之间的切换
信号量
共享内存会带来多进程竞争共享资源的问题,严重时会导致数据的错乱,所以需要引入一种保护机制,信号量就实现了这样的保护机制。
信号量就是一个整数计数器,主要是为了实现进程间的同步与互斥,并不用于缓存数据。
两个进程互斥访问共享资源,信号量为1
两个进程之间同步,信号量为0
信号
信号是进程间通信方式中唯一的异步通信机制,我们可以在任意时间给进程发送信号,用户进程接受到信号后需要进行以下处理:捕捉信号,执行相关 *** 作,忽略该信号
Socket
实现不同主机上进程跨网络的通信,或者同一主机上不同进程的通信(TCP/UDP)
10 死锁产生死锁的条件
互斥条件
不可剥夺条件
持有并保持条件
环路等待条件
死锁预防
破坏产生死锁的四个必要条件的任意一个,一般来讲,我们都是破坏循环等待条件,要破坏这个条件,可以采用顺序资源分配法
死锁避免
死锁避免的经典算法就是银行家算法,这个算法的思想是:当进程请求资源的时候,先查看请求的资源是否大于当前进程的最大资源请求,大于则直接拒绝资源请求;否则进入下一轮检查,查看该进程请求的资源是否大于当前该资源的剩余量,大于则拒绝该请求;否则尝试给该进程分配资源并进行安全性检查,安全性检查通过则表示可以分配,否则此次分配时不安全的,即推迟分配。
涉及到的数据结构:
可利用资源向量,一维数组,j处元素表示当前元素还有多少可以用来分配
最大需求矩阵,给出了每个进程对于每种资源的最大需求
分配矩阵,给出了当前每个进程对于每种资源的持有信息
需求矩阵,给出了当前每个进程对于每种资源还需要多少。需求矩阵=最大需求矩阵-分配矩阵
银行家算法流程:当有一个进程请求资源A时
查看当前请求资源A的量是否大于该进程当前的最大需求量,大于则拒绝分配,否则进入下一步
查看当前请求资源A的量是否大于当前资源A的剩余量,大于则拒绝分配,否则进入下一步
尝试给进程A分配资源A,然后更新上述四个数据结构的信息
对分配进行安全性检查,若当前分配不安全则推迟分配
安全性检查算法
该算法就是尝试找到一个能够使得当前资源分配安全的进程资源分配序列,找到则说明此次分配安全,否不安全,具体流程如下:
计算资源分配后的可利用资源向量
将该向量与需求矩阵中的各行进行比较,大于则尝试分配,并将当前进程加入安全序列,否则终止
循环进行第二步,若能够得到安全序列则分配安全,不能得到则分配不安全,推迟分配
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)