计算机操作系统学习笔记(4)
进程(process)管理
定义:进程是⼀个具有⼀定独⽴功能的程序在⼀个数据集合是的⼀次动态执⾏过程
组成
包含了程序晕⾏的所有状态信息
程序的代码
程序处理的数据
程序计数器中的值,指⽰下⼀条将运⾏的程序
⼀组通⽤的寄存器的当前值,堆、栈
⼀组系统资源(内存⽹络⽂件系统等)
进程与程序的联系:
程序是产⽣进程的基础
程序的每次运⾏将产⽣不同的进程
进程是程序功能的体现
通过多次执⾏,⼀个程序可对应多个进程;通过调⽤关系,⼀个进程可包括多个程序
进程与程序的区别:
进程是动态的,程序是静态的:程序是有序代码的集合;进程是程序的执⾏,进程有⽤户态、核⼼态进程是暂时的,程序是永久的:进程是⼀个状态变化的过程,程序可长久保存
进程与程序组成不同:进程由程序、数据、进程控制块(即进程状态信息)组成
进程的特点:
动态性:可动态创建、结束进程
并发性:进程可以被独⽴调度并占⽤处理机运⾏
独⽴性:不同进程的⼯作不互相影响
制约性:因访问共享数据、资源或进程间同步⽽产⽣制约
进程控制块(PCB):
进程的创建:为该进程⽣成⼀个PCB
进程的终⽌:回收他的PCB
进程的组织管理:通过对PCB的组织管理实现的
PCB包含的信息:
进程的标识信息:如进程的标识,本进程的产⽣着的标识(⽗进程标识),⽤户标识
处理机状态信息保存区:保存进程运⾏现场信息
⽤户可见寄存器:⽤户可以使⽤的数据,地址等寄存器
控制和状态寄存器:如程序计数器(PC),程序状态字(PSW)
栈指针:过程调⽤、系统调⽤、中断处理和返回时需要⽤到它
进程的控制信息:
调度和状态信息:⽤于操作系统调度进程并占⽤处理机的使⽤
进程间通信信息:为⽀持进程间的与通信相关的各种标识、信号、信件等,这些信息存在接收⽅的PCB中存储管理信息:包含有指向本进程影响存储空间的数据结构,以及⽗进程等进程间的关系
进程所⽤的资源:说明由进程打开、使⽤的系统资源,如打开的⽂件等
有关数据结构连接信息:进程可以连接到⼀个进程队列中,或连接到相关的其他进程的PCB
PCB的组织⽅式:
链表:较多使⽤,因为进程是动态的插⼊删除
索引表
进程状态
进程的⽣命期管理:
进程创建
进程运⾏
进程等待
进程唤醒
进程结束
进程创建:
引起进程创建的主要事件*
系统初始化时,init进程
⽤户请求创建⼀个新的进程
正在运⾏的进程执⾏了创建进程的系统调⽤
进程等待(阻塞):
请求并等待系统服务,⽆法马上完成
启动某种操作,⽆法马上完成
需要的数据没有到达
进程只能⾃⼰阻塞⾃⼰,因为只有进程⾃⾝才能知道何时需要等待某种事件的发⽣,这是其他处于准备的进程可以由操作系统调度运⾏
进程唤醒:
被阻塞的进程需要的资源可被满⾜
被阻塞进程等待事件到达
然后将该进程的PCB插⼊到就绪队列
阻塞进程只能被其他进程或操作系统唤醒
进程结束:
正常退出(⾃愿的)
错误退出(⾃愿的)
致命错误(强制性的)
被其他进程所杀(强制性的)
进程状态变化模型:
进程挂起:
进程在挂起时,进程不占⽤内存空间,进程的映像在硬盘上
阻塞挂起状态:进程在外存并等待某事件的出现
就绪挂起状态:进程在外存,只要进⼊内存即可运⾏
从内存到外存,可能有以下⼏种情况:
塞到阻塞寒挂起:没有进程处于就绪状态或就绪进程要求更多内存资源时,会进⾏这种转换,以提交新进程或运⾏就绪进程
就绪到就绪挂起:当有⾼优先级阻塞(系统认为会很快就绪的) 进程和低优先就绪进程时,系统会选择挂起低优先级就绪进程
运⾏到就绪挂起:对抢先式分时系统,当有⾼优先级阻塞挂起进程因事件出现⽽进⼊就绪挂起时,系统可能会把运⾏进程转到就绪挂起状态
在外存时的状态转换:
阻塞挂起到就绪挂起:当有阻塞挂起进程因相关事件出现时,系统会把阻塞挂起进程转换为就绪挂起进程。
解挂/激活:把⼀个进程从外存转到内存; 可能有以下⼏种情况:
就绪挂起到就绪:没有就绪进程或挂起就绪进程优先级⾼于就绪进程时,会进⾏这种转换
阻塞挂起到阻塞:当⼀个进程释放⾜够内存时,系统会把⼀个⾼优先级阻塞挂起(系统认为会很快出现所等待的事件) 进程转换为阻塞进程
状态队列
由操作系统来维护⼀组队列,⽤来表⽰系统当中所有进程的当前状态
不同的状态分别⽤不同的队列来表⽰(就绪队列、各种类型的阻塞队列)
每个进程的PCB都根据它的状态加⼊到相应的队列当中,当⼀个进程的状态发⽣变化时,它的PCB从⼀个状态队列中脱离出来,加⼊到另外⼀个队列
线程:进程当中的⼀条执⾏流程
进程管理系统资源,线程作为进程的重要组成部分,由线程完成执⾏的过程。⼀个进程可以有多个线程,各线程共享进程提供的资源平台线程的优点:
⼀个进程中可以存在多个进程
各线程之间可以并发的执⾏
各个线程之间可以共享地址空间和⽂件等资源
线程的缺点:
⼀个线程崩溃,会导致其所属进程的所有线程崩溃
单线程与多线程资源对⽐图
多线程共享代码、数据、⽂件等资源
多线程有各⾃⾃⼰的寄存器堆栈
进程与线程的⽐较:
进程是资源分配单位,线程是CPU调度单位进程间通信最快的方式
进程拥有⼀个完整的资源平台,⽽线程只独享必不可少的资源,如寄存器和栈
线程同样具有就绪、等待、执⾏三种基本状态,同样具有状态之间的转换关系
线程能减少并发执⾏的时间和空间的开销:
- 线程的创建时间⽐进程短
- 线程的终⽌时间⽐进程短
- 统⼀进程内的线程切换时间⽐进程短
- 由于同⼀进程的个线程间共享内存和⽂件资源,可直接进⾏不通过内核的通信
线程的实现:
⽤户线程:操作系统看不到的线程,由⽤户线程库管理
内核线程:是操作系统管理的线程
⽤户线程:
在⽤户空间实现的线程机制,它不依赖于操作系统的内核,由⼀组⽤户级的线程库函数来完成线程的管理,包括进程的创建、终⽌、同步和调度等
由于⽤户线程的维护由相应进程来完成(通过线程库函数),不需要操作系统内核了解⽤户线程的存在,可⽤于不⽀持线程技术的多进程操作系统
每个进程都需要它⾃⼰私有的线程控制块(TCB) 列表,⽤来跟踪记录它的各个线程的状态信息(PC、栈指针、寄存器),TCB由线程库函数来维护;
⽤户线程的切换也是由线程库函数来完成,⽆需⽤户态/核⼼)态切换,所以速度特别快*
允许每个进程拥有⾃定义的线程调度算法。
⽤户线程缺点:
阻塞性的系统调⽤如何实现? 如果⼀个线程发起系统调⽤⽽阻塞,则整个进程在等待
当⼀个线程开始运⾏后,除⾮它主动地交出CPU的使⽤权,否则它所在的进程当中的其他线程将⽆法运⾏
由于时间⽚分配给进程,故与其它进程⽐,在多线程执⾏时,每个线程得到的时间⽚较少,执⾏会较慢
内核线程:
是指在操作系统的内核当中实现的⼀种线程机制,由操作系统的内核来完成线程的创建、终⽌和管理
在⽀持内核线程的操作系统中,由内核来维护进程和线程的上下⽂信息(PCB和TCB)
线程的创建、终⽌和切换都是通过系统调⽤/内核函数的⽅式来进⾏,由内核来完成,因此系统开销较⼤
在⼀个进程当中,如果某个内核线程发⾛2系统调⽤⽽被阻塞,并不会影响其他内核线程的运⾏
时间⽚分配给线程,多线程的进程获得更多CPU时间
Windows NT和Windows 2000/XP⽀持内核线程
轻量级进程:
它是内核⽀持的⽤户线程。⼀个进程可有⼀个或多个轻量级进程,每个量级进程由⼀个单独的内核线程来⽀持。(Solaris/Linux)
上下⽂切换
停⽌当前运⾏进程(从运⾏太转为其他状态)并且调度其他进程(转为运⾏状态),操作系统将PCB放⼊相应队列中,就绪队列、等待I/O 队列(分为每个设备的队列)、僵⼫队列
必须在切换之前存储许多部分的进程上下⽂
必须能够在之后恢复他们,所以进程不能显⽰他曾经被暂停过
必须快速(上下⽂切换时⾮常频繁)
需要储存:
寄存器(PC等)、CPU状态
⼀些时候可能会费时,所以我们应该尽量避免
进程控制:
创建进程,fork() ⽗进程创建⼦进程
加载和执⾏进程,EXEC()加载程序取代当前运⾏的进程
等待和终⽌进程,wait()
Fork()的简单实现:
对⼦进程分配内存,复制⽗进程的内存和CPU寄存器到⼦进程中,开销⼤
99%调⽤fork是为了接下来调⽤exec:fork中内存复制没⽤,⼦进程将可能关闭打开的⽂件和连接,开销⾼
优化:即省略复制⽗进程到⼦进程的过程
使⽤Vfork(),早期LINUX采⽤虚拟fork
⼀个创建进程的系统调⽤,不⽤创建⼀个同样的内存映像
⼀些时候是轻量级fork,只是复制了⼀⼩部分⽗进程的内容
⼦进程应该⼏乎⽴即调⽤exec
现在不再使⽤,如果采⽤了copy on write COW技术(通过OS的虚存管理,只复制了⽗进程meta元数据即页表,指向的是同⼀地址空间,对某个地址单元进⾏写操作时触发异常,⽗⼦各把要⽤的页复制成两份,使⽗进程和⼦进程拥有不同的地址。按需,光读不⽤复制,写才⽤)
等待:
wait():⽗进程⽤来等待⼦进程的结束,⼀个⼦进程向⽗进程返回⼀个值,⽗进程必须接受这个值并处理。
为什么要让⽗进程等?⽽不是直接结束? :
当进程执⾏完毕退出后,⼏乎所有资源都回收到OS中。但有个资源很难回收,就是PCB,PCB是代表进程存在的唯⼀标识,OS要依据PCB 执⾏回收。这个功能由⽗进程完成。
Wait()使⽗进程睡眠,当⼦进程调⽤exit时操作系统解锁⽗进程,将通过exit传递得到的返回值作为wait调⽤的⼀个结果(连同⼦进程的pid⼀起)。关闭所有打开的⽂件和连接,释放内存,释放⼤部分⽀持进程的OS结构,检查⽗进程是否存活。
如果⽗进程存活,它保留exit结果的值直到⽗进程需要它,进⼊僵⼫(zombie/defunct)状态。
如果⽗进程先于⼦进程死掉了,它释放所有的数据结构,这个进程死亡。
最后清理所有等待的僵⼫进程。
最早的进程ROOT进程/主动进程/RIT进程会定期扫描PCB列表,到僵⼫状态的进程并清理,使OS中不会僵⼫越积越多。
如果这⾥没有⼦进程存活,wait⽴刻返回。如果有⽗进程的僵⼫等待,WAIT⽴即返回其中⼀个值并解除僵⼫状态。
僵⼫状态:
僵⼫状态就是⼦进程调⽤了EXIT但⽗进程还没有wait执⾏完毕的时候。此时⼦进程⽆法正常⼯作,只是等待被⽗进程回收
状态转换图:
执⾏EXEC()时,进程可以处于不同的状态。⾸先是runnig, 然后加载(加载进内存)、运⾏,加载时间长要有可能running->blocked。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论