操作系统四大特质:并发,共享,虚拟,异步
都是基于进程而产生的,并从进程的角度对操作系统进行研究。在操作系统中,进程是一个极其重要的概念。
在计算机中按ctrl + shift + esc,打开任务管理器,可以看到后台有很多进程
在多道程序环境下,程序的执行属于并发执行。
并发执行的特点:
这决定了通常的程序是不能参与并发执行的。
为了使程序能并发执行,并且可以对并发执行的程序加以描述和控制,由此引入了进程的概念。
从不同的角度可以有不同的定义,比较典型的定义:
动态性
并发性
独立性
异步性
制约性
联系:
区别:
在学习数据结构的时候,有一个很经典的公式:
程序 = 算法 + 数据结构
描述进程的数据结构: 进程控制块PCB
为了使参与并发执行的每个程序(含数据)都能独立运行,在操作系统中必须为之配置一个专门的数据结构,称为进程控制块(Process Control Block).
PCB: 操作系统管理控制进程运行所用的信息集合。
系统利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程
PCB是进程存在的唯一标志
由程序段,相关的数据段,PCB 三部分构成进程实体(进程映像)
一般情况下,进程实体简称为进程。
创建进程实质上是创建进程实体中的PCB,
撤销进程实质上是撤销进程实体中的PCB
进程和程序是两个不同的概念,进程具有程序所不具备的PCB,
(一)进程标识信息
进程标识符
(二)处理机状态信息保存区
通用寄存器
又称用户可视寄存器,是用户程序可以访问的
用于暂存信息,在大多数处理机中,有8~32个通用寄存器
指令计数器
存放了要访问的下一条指令的地址
程序状态字PSW
其中含有状态信息,如条形码,执行方式,中断屏蔽标志
用户栈指针
每一个用户进程都有一个或若干个与之相关的系统栈,用于存放过程和系统调用及调用地址
栈指针指向该栈的栈顶
过程调用/系统调用/中断处理 和返回时需要用到它
(三)进程调度信息
进程状态
指明进程的当前状态,作为进程调度和对换时的依据
进程优先级
是用于描述进程使用处理机的有限级别的一个整数,优先级高的进程应优先获得处理机
进程调度所需的其它信息
与采用的进程调度算法有关,如进程已等待的CPU的时间总和,进程已执行的时间综合
事件
是指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因
(四)进程控制信息
程序和数据的地址
当调度到该进程时,可以从PCB中找到其程序和数据
进程同步和通信机制
实现进程同步和进程通信时必需的机制
如消息队列指针,信号量等
资源清单
列出了进程在运行期间除CPU外所需的全部资源
另外还有一张已分配到该进程的资源的清单
链接指针
给出了本进程(PCB) 所在队列中的下一个进程的PCB的首地址
还是刚开始的那张图,可以看到有一百多个进程,通常在一个系统中会有数十个,数百个甚至上千个进程,那么就会有对应的PCB
如果这些PCB没有加以有效的管理,那么系统就全都乱套了。
如何用适当的方式将这些PCB 组织起来呢,既然PCB是一个数据结构,那么肯定离不开数据结构中的组织方式,常用的组织方式有三种
所有的PCB都在一张线性表中,该表的首址存放在内存的一个专用区域中。
同一状态的进程其PCB 成一链表,多个状态对用多个不同的链表
=自闭状态(开个玩笑)
为增强进程控制块(PCB) 对数据及操作的完整性要求以及增强管理的灵活性,通常在操作系统中又为进程引入了两种常见状态:
创建状态,终止状态
进程是由创建而产生。
创建进程的步骤:
但是如果进程所需的资源尚不能得到满足,创建工作就无法完成,进程不能被调度运行,此时进程所处的状态被称为创建状态
引入创建状态是为了保证进程的调度必须在创建工作完成后执行,确保对进程控制块(PCB) 操作的完整性
也增加了操作系统的灵活性,比如可以推迟新进程的提交(创建状态)
终止进程的步骤:
进入终止状态有下面几种可能:
但是终止状态并不代表进程被销毁。
进入终止状态的进程以后不能再执行,但是再操作系统中仍然保留记录,供其它进程收集,一旦其它进程完成了对其信息的提取,操作系统将删除该进程。
进程没有占用内存空间,称为进程挂起
挂起就是把一个进程从内存转到外存。
挂起有以下几种情况:
操作系统中引入了一个对进程的重要操作 ——挂起操作。
当挂起操作应用于某个进程时,该进程将被挂起,意味着进程将处于静止状态。
如果进程正在执行,它将暂停执行。
如果进程原本处于就绪状态,则该进程此时暂时不接受调度。
与挂起操作对应的是激活操作
进程挂起有两种状态:
是基于系统和用户的如下需要
在引入挂起原语Suspend 和 激活原语Active 后,进程转换如下
顾名思义,进程控制就是控制进程,对系统中的所有进程实施有效的管理。
创建进程,撤销进程,进程转换等都属于进程控制。
操作系统中,控制进程的程序段称为原语,
原语的特点是执行期间不允许中断,它是一个不可分割的基本单位。
任何进程都是在操作系统内核的支持下运行的,是与内核紧密相关的。
允许一个进程创建另一个进程。
创建者称为父进程,被创建的进程称为子进程。
子进程可以继承父进程拥有的资源。子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。
在撤销父进程时,必须同时撤销其所有的子进程。
引起进程创建的原因。
创建新进程的过程如下:
引起进程终止的原因:
终止进程的过程( 撤销原语)
为什么进程的阻塞和唤醒要放在一起呢?
因为Block原语和Wakeup原语是作用相反的原语,必须成对使用
(执行中的)进程阻塞的原因:
进程期待的事件未发生,如:
阻塞进程的过程(阻塞原语)
当被阻塞进程所期待的事情发生后,调用唤醒原语(Wakeup),将等待该事件的进程唤醒。
唤醒进程的过程(唤醒原语)
进程的唤醒是被动的行为,只能通过别的进程或操作系统唤醒
进程切换是指处理机从一个进程的运行转到另一个进程上运行,这个过程中,进程的运行环境发生了实质性的变化。
进程切换的过程:
注意:进程切换与处理机模式切换不同,模式切换时,处理机逻辑上可能还在同一进程中运行。
如果进程因中断或异常进入到核心态运行,执行完后又回到用户态刚被中断的程序运行,操作系统只需要恢复进入内核时所保存的CPU现场,无需改变当前的进程环境信息。
但若切换进程,当前运行进程改变了,当前进程的环境信息也需要改变。、
进程通信是指进程间的信息交换。
进程之间是相互独立的
PV操作(就是进程的互斥和同步)是低级通信方式。高级通信方式是指以较高的额效率传输大量数据的通信方式。
主要有以下三个类:
通信的进程之间存在一块可以直接访问的共享空间,通过对这片共享空间进行读/写操作实现进程之间的信息交换。
在对共享空间进行读/写操作时,需要使用同步互斥工具(如PV操作)对共享空间的读/写进行控制。
共享存储又分为两种:
低级方式的共享是基于数据结构的共享
高级方式的共享是基于存储区的共享
操作系统只负责为通信进程提供可共享使用的存储空间和同步互斥工具,
数据交换则由用户自己安排 读/写指令 完成
用户进程空间一般是独立的,进程运行期间一般不能访问其它进程的空间,要想让两个用户进程共享空间必须通过特殊的系统调用实现,进程内的线程是自然共享进程空间的
消息交换的单位是消息或报文(计算机网络中将消息称为 报文)
消息传递系统中,进程间的数据交换是以格式化的消息(Message) 为单位的。
若进程之间不存可以直接访问的共享空间,必须利用操作系统提供的消息传递方法实现进程通信,进程通过系统提供的发送消息和接受消息两个原语进行数据交换
发送进程直接发送消息到接受进程,并将消息挂在接收进程的的消息缓冲队列上,接收进程从消息缓冲队列中取得消息
系统提供两条通信原语
发送进程把消息发送给信箱,接受进程从信箱中取得消息,这种通信方式又称为信箱通信方式。
信箱通信方式广泛应用于计算机网络中,相应的通信系统称为电子邮件系统。
消息在信箱中可以安全的保存,只允许核准的目标用户随时读取,可实现非实时通信
私用信箱
公用信箱
共享信箱
1) 管道通信方式建立在文件系统的基础上,利用共享文件来连接两个互相通信的进程,此共享文件称为管道(Pipe)
2) 管道是指用于连接一个读进程和一个写进程,以实现他们之间通信的共享文件
互斥
当一个进程正在对管道进行读/写操作时,另一个进程必须等待
同步
当写(输入)进程把一定的数据(如4K)写入管道后,便去睡眠等待,直到读(输出)进程取走数据后再把它唤醒。
当读进程发现管道空时,也应睡眠等待,直到写进程将消息写入管道后,才将它唤醒
判断对方是否存在
只有在确定对方存在时才能进行通信
从管道读数据是一次性操作,数据一旦被读取,它就从管道中被抛弃,释放空间以便写更多的数据。
管道只能采用半双工通信,即某一时刻只能单向传输。
要实现父子进程双方互相通信,需要定义两个管道。
回顾一下为什么要引入进程:
引入进程的目的,是为了更好地使多道程序并发执行,以提高资源利用率和系统吞吐量,增加并发程度。
进程的两个属性:
既然进程拥有资源,还是独立调度和分派的基本单位,已经能够使程序并发执行了。为什么还要引入线程呢?
正如古话所说:杀鸡焉用牛刀,用进程处理一些小的比较复杂的事件,用进程处理就会显得很笨重,付出了较大的时空开销,这就限制了系统中所设置的进程的数目,而且进程切换也不宜过于频繁,限制了并发程度的进一步提高。所以把传统进程称为中兴进程。
而线程又称为轻型进程或进程元。
调度的基本单位
在传统OS中,进程是作为独立调度和分派的基本单位,因而进程是能独立运行的基本单位。在每次被调度时,都需要进行上下文切换,开销很大。
引入线程的OS中,把线程作为调度和分派的基本单位,而进程是拥有资源的基本单位
同一进程中,线程切换不会引起进程切换
但从一个进程中的线程切换到另一个进程中的线程时,必然会引起进程的切换
并发性
多个线程(同一进程或不同进程)之间可以并发执行
拥有资源
进程是拥有资源的基本单位,线程不拥有系统资源,如果拥有系统资源,那么线程和进程就是一样的了。但是线程也又一点必不可少的,能保证独立运行的基本资源,线程可以访问其隶属进程的系统资源。
系统开销
线程切换时,只需要保存和设置少量寄存器内容,开销很小。
而且由于统一进程的所有都具有相同的地址空间(共享进程的地址空间),线程之间的同步与通信非常容易实现,甚至无需操作系统干预
地址空间和其它资源
进程的地址空间之间互相独立,同一进程的各线程间共享进程的资源,某进程内的线程对于其它进程不可见
通信方面
进程间通信(IPC)需要进程同步和互斥手段的辅助,以保证数据的一致性,而线程间可以直接读/写进程数据段(如全局变量)来进行通信。
线程的实现方式可以分为两类:
OS中的所有进程,无论是系统进程还是用户进程,都是在操作系统内核的支持下运行的,是与内核紧密相关的。而内核支持线程KST同样是在内核的支持下运行的,他们的创建,阻塞,撤销,切换都是在内核空间中实现的。
内核空间也为每一个内核线程设置了一个线程控制块TCB,内核根据该控制块而感知某线程的存在,并对其加以控制。
KST的四个优点:
KST的缺点:
用户进程的线程在用户态运行
用户线程切换时,需要从用户态转到核心态进行,模式切换的开销较大。
用户级线程是在用户空间中实现的,对线程的创建,撤销,同步,通信等功能,都无需内核的支持,即用户级线程是与内核无关的。这些线程的任务控制块都是设置在用户空间,线程所执行的操作也无需内核支持,因而内核完全不知道用户级线程的存在。
注意!!!
设置了用户级线程的系统,其调度仍是以进程为单位进行的
设置了内核支持线程的系统,其调度便是以线程为单位进行的。
ULT的优点:
ULT的缺点:
有些OS同时支持KST和ULT,提供了组合方式ULT/KST 线程,由此产生了不同的多线程模型,即实现了用户级线程和内核级线程的连接方式。
缺点:
缺点: