1前驱图和程序执行
前趋图(Precedence Graph):是一个有向无循环图,记为DAG(Directed Acyclic Graph),前趋图中必须不存在循环, 该图通常用于 表现事务之间先后顺序的制约关系 。
顺序执行前驱图:
并发执行前驱图:
1.1程序是如何执行的?
1.1.1程序顺序执行的特征
顺序性:指处理机严格地按照程序所规定的顺序执行,即每一操作必须在下一个操作开始之前结束。
封闭性:即程序运行时独占全机资源,资源的状态(除初始状态外)只有本程序才能改变它,程序一旦开始执行,其执行结果不受外界因素影响。
可再现性:指只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“走走停停”地执行,都可获得相同的结果。
1.1.2程序并发执行的特征
间断性:程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使在这些并发执行的程序之间形成了相互制约的关系。
失去封闭性:当系统中存在着多个可以并发执行的程序时,系统中的各种资源将为它们所共享,致使其中任一程序在运行时,其他环境都必然会受到其他程序的影响。
不可再现性:程序在并发执行时,由于失去了封闭性,也将导致其又失去可再现性
1.2为什么要发明进程?
从上面的概念我们可以知道 程序在并发执行时,由于失去了封闭性,其计算结果必将与并发程序的执行速度、方向有关,从而使程序的执行失去了可再现性。 换言之,程序经过多次执行后,虽然它们执行时的环境和初始条件相同,但得到的结果却各不相同。 因为大部分程序执行要求最终结果相同,比如修改数据库。所以,通常的程序是不能参与并发执行的。为了能使程序并发执行,并对并发执行的程序加以描述和控制,引入了“进程”的概念。 引入进程的目的是为了使其进程实体能和其他进程实体并发执行,实现操作系统的并发性和共享性(最基本的两个特征)。
引入进程相当于是为静态的程序,增加了运行状态的信息以及数据存储位置的信息。使得我们知道程序执行状态,变成动态的执行。
2 进程描述
2.1进程的组成
进程(Process):是动态的,是程序的一次执行过程,同一个程序多次执行会对应多个进程
问题1:如何判断一个数据在PCB还是在程序段、数据段?
操作系统管理进程 所需的数据都在PCB中
局部变量等在数据段,代码在程序段。
问题2:程序和进程的区别?
程序:是静态的,就是个存放在磁盘里的可执行文件。
进程:是动态的,是程序的一次执行过程。 同一个程序多次执行会对应多个进程。
进程实体(进程映像):是静态的文件,相当于增加了PCB和数据段的程序。
2.2 进程的特征
2.3进程的组织方式
链接方式。即把具有相同状态进程的PCB分别通过PCB中的链接字链接成一个队列。
索引方式。即系统根据所有进程状态的不同,建立几张索引表。
2.4 进程的状态与转换
2.4.1 进程的状态
2.4.2 进程的转换
3 进程控制
进程控制就是要实现进程状态转换。
3.1 进程控制宏观操作
3.2 如何使用原语实现进程控制
进程控制会导致进程状态的转换。无论哪个原语,要做的无非也是三类事情:
1.更新PCB中的信息
(如修改进程状态标志、将运行环境保存到PCB、从PCB恢复运行环境) a.所有的进程控制原语一定都会修改进程状态标志 b.剥夺当前运行进程的CPu使用权必然需要保存其运行环境c.某进程开始运行前必然要恢复期运行环境.
2.将PCB插入合适的队列
3.分配/回收资源。
原语的原子性——执行无歧义
原语是内核中最接近硬件的部分,执行特点是一气呵成的执行完所有语句。 原子性的实现需要“关中断”“开中断”特权指令,关闭中断CPU检查使执行时无法被中断。 正常情况:CPU每执行完一条指令都会例行检查是否有中断信号需要处理,如果有,则暂停运行当前这段程序,转而执行相应的中断处理程序。 CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查,才会去执行关中断期间的外部中断程序。这样,关中断、开中断之间的这些指令序列就是不可被中断的,这就实现了“原子性”。
进程的切换——切换原语
3.3 相关原语
3.3.1进程的创建
3.3.2进程的终止
3.3.3进程的阻塞和唤醒
3.3.5进程的切换
4 进程通信
进程通信:就是进程之间的信息交换。进程通信需要操作系统支持
进程通信的由来:进程是分配系统资源的单位(包括内存地址空间),因此各进程拥有的内存地址空间相互独立。为了保证安全,一个进程不能直接访问另一个进程的地址空间。 进程之间不能直接访问对方的资源,但是需要相互交换信息,比如,抖音分享视频链接。此时就需要进程通信。
实现进程通信的三种方式
4.1 共享存储
基于数据结构的共享
基于存储区的共享
4.2消息传递(最广泛使用)
进程间的数据交换以格式化的消息(Message)为单位(不同环境下,消息格式不同)。 进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。
应用场景: 若通信的进程之间不存在可直接访问的共享空间,则必须利用操作系统提供的消息传递方式实现进程通信。 在计算机网络中,消息又称为报文;在微内核与服务器之间的通信也都是采用了消息传递机制。
基于消息传递的通信方式属于高级通信方式,因其实现方式的不同,可进一步分为2类:
直接通信
间接通信
注:由于PCB是保存在操作系统内核中,所以消息队列也是在内核中
4.3管道通信
管道通信过程
管道通信就是用一个传输字符流格式的管道(共享文件)进行通信,
1.数据以字符流的形式写入管道,当管道写满时,写进程的write()系统调用将被阻塞,等待读进程将数据取走。
2.当读进程将数据全部取走后,管道变空,此时读进程的read()系统调用将被阻塞。
如果没写满,就不允许读。 如果没读空,就不允许写。 管道中的数据一旦被读出,就彻底消失。
因此,当多个进程读同一个管道时,可能会错乱。对此,通常有两种解决方案:①一个管道允许多个写进程,一个读进程.②允许有多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据(Linux 的方案)。
管道通信特点
管道缓冲区大小和操作系统内存页面一样,Linux就是4KB。
管道的底层数据结构是一个循环队列。
管道只能采用半双工通信,
5 线程
5.1 线程的概念
5.1 线程的引入
线程就是一个进程的若干功能,比如QQ可以同时使用文字聊天和视频聊天两种功能。 传统的进程只能顺序的实现若干功能,但是引入线程技术,可以让线程并发的执行,也就可以同时实现若干功能了。
5.2 线程的定义
可以把线程理解为“轻量级进程”。LWP(Light Weight Process) 线程,是一个基本的CPU执行单元,也是程序执行流的最小单位。 引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。线程则作为处理机的分配单元。
5.3 线程的属性
1、由线程ID、程序计数器、寄存器集合和堆栈组成。
2、线程是进程中的一个实体,是被系统独立调度和分派的基本单位。
3、线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。
4、一个线程可以创建和撤销另一个线程,同个进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。
5、线程也有就绪、阻塞和运行三种基本状态。
5.4 线程与进程的比较
调度:在传统的OS中,进程是资源分配、调度的基本单位。引入线程后,进程是资源分配的基本单位,线程是调度的基本单位 在同一进程中,线程的切换不会引起进程切换。 在不同进程中进行线程切换,如从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。
拥有资源:不论是传统操作系统、还是有线程的操作系统,进程都是拥有资源的基本单位,而线程不拥有系统资源(只有一点必不可少的资源),但线程可以访问其隶属进程的系统资源。
并发性:在传统的OS中,只有进程间并发。在引入线程后,各线程间也能并发,提升了并发度。 系统开销:传统的进程间并发时,需要切换进程的运行环境,系统开销很大。而线程间并发时,如果是同一进程内的线程切换,则不需要切换进程环境,系统开销小。