文章目录
进程与线程
1.进程
(1)什么是进程?
程序:是 静态 的,就是个存放在磁盘里的可执行文件,就是一系列的指令集合。
进程(Process):是 动态 的,是程序的一次执行过程(是一个程序及其数据在处理机上顺序执行时所发生的活动)
(2)进程的组成
准确来说, PCB,程序段,数据段构成的是进程实体(进程映像)。进程映像是静态的,进程是动态的。
其中PCB是进程存在的唯一标志。PCB 是给操作系统用的。程序段、数据段是给进程自己用的
(3) 进程的特征
2.进程的组织
主要有两种方式:
3.进程的状态与转换
首先三种基本状态:运行态,就绪态,阻塞态
另外还有两种状态:创建态和终止态
5种状态之间的转换:
注意:从运行态到阻塞态是主动行为,而从阻塞态到就绪态是被动的
4.进程控制
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能。(进程控制就是要实现进程状态转换)
进程控制通过原语来实现
无论哪个进程控制原语,要做的无非三类事情:
- 更新PCB中的信息
a. 所有的进程控制原语一定都会修改进程状态标志
b. 剥夺当前运行进程的CPU使用权必然需要保存其运行环境
c. 某进程开始运行前必然要恢复期运行环境 - 将PCB插入合适的队列
- 分配/回收资源
进程的创建
进程的终止
进程的阻塞和唤醒
5.进程通信
进程通信就是指进程之间的信息交换
为了保证安全,一个进程不能直接访问另一个进程的地址空间。
但是进程之间的信息交换又是必须实现的。为了保证进程间的安全通信,操作系统提供了一些方法。
主要有三种方法:
6.线程
(1)什么是线程?
可以把线程理解为“轻量级进程”
引入线程机制后,并发带来的系统开销降低,系统并发性提升
线程是一个基本的CPU执行单元,也是程序执行流的最小单位。
引入线程后,进程只作为除CPU之外的系统资源的分配单元(如打印机、内存地址空间等都是分配给进程的)。线程则作为处理机的分配单元。
(2)引入线程后,发生了什么变化?
(3)线程的属性
(4)线程的实现方式
第一种用户级线程:
- 用户级线程由应用程序通过线程库实现,所有的线程管理工作都由应用程序负责(包括线程切换)
- 用户级线程中,线程切换可以在用户态下即可完成,无需操作系统干预。
- 在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。“用户级线程”就是“从用户视角看能看到的线程”
- 优缺点
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行
第二种内核级线程:
大多数现代操作系统都实现了内核级线程(如Windows、Linux)
- 内核级线程的管理工作由操作系统内核完成。
- 线程调度、切换等工作都由内核负责,因此内核级线程的切换必然需要在核心态下才能完成。
- 操作系统会为每个内核级线程建立相应的TCB(Thread Control Block,线程控制块),通过TCB对线程进行管理。“内核级线程”就是“从操作系统内核视角看能看到的线程”
- 优缺点
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
第三种组合方式
用户和内核线程的组合
(5)多线程模型
有些系统同时支持用户线程和内核线程,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型
处理机调度
1.调度
2.调度的目标
3.调度算法
(1)先来先服务(FCFS)
(2)短作业优先(SJF)
(3)高响应比优先(HRRN)
(4)时间片轮转(RR)
(5)优先级调度
(6)多级反馈队列
同步与互斥
1.进程的同步&互斥
(1)同步
读进程和写进程并发地运行,由于并发必然导致异步性,因此“写数据”和“读数据”两个操作执行的先后顺序是不确定的。而实际应用中,又必须按照“写数据→读数据”的顺序来执行的。(解决异步问题——进程同步)
同步亦称直接制约关系,它是指为完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。
(2)互斥
我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备(比如摄像头、打印机)都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。
对临界资源的访问,必须互斥地进行。互斥,亦称间接制约关系。进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。
2.进程互斥的软硬件实现
(1)软件实现
(2)硬件实现
3.信号量机制
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作。信号量其实就是一个变量 ,可以用一个信号量来表示系统中某种资源的数量(比如:系统中只有一台打印机,就可以设置一个初值为 1 的信号量)
一对原语:wait(S) 原语和 signal(S) 原语,可以把原语理解为我们自己写的函数,函数名分别为 wait和 signal,括号里的信号量 S 其实就是函数调用时传入的一个参数。——通常简称P,V操作(原语申请和释放)
(1)整型信号量
- 用一个整数型变量作为信号量,数值表示某种资源数
- 整型信号量与普通整型变量的区别:对信号量只能执行初始化、P、V三种操作
- 整型信号量存在的问题∶不满足让权等待原则
(2)记录型信号量
- S.valte表示某种资源数,S.L指向等待该资源的队列
- Р操作中,一定是先 S.value–,之后可能需要执行block 原语
- V操作中,一定是先S.value++,之后可能需要执行wakeup 原语
- 可以用记录型信号量实现系统资源的“申请"和“释放"及进程同步和互斥
4.信号量机制的应用
P( S ) —— 申请一个资源S,如果资源不够就阻塞等待
V( S ) —— 释放一个资源S,如果有进程在等待该资源,则唤醒一个进程
5.经典同步问题
(1)生产者与消费者
(2)吸烟者问题
(3)哲学家问题
6.管程
死锁
1.定义
在并发环境下,各进程因竞争资源而造成的一种互相等待对方手里的资源,导致各进程都阻塞,都无法向前推进的现象,就是“死锁”。发生死锁后若无外力干涉,这些进程都将无法向前推进
死锁 & 饥饿 & 死循环
2.死锁的四个必要条件
产生死锁必须同时满足以下四个条件,只要其中任一条件不成立,死锁就不会发生。
(1)互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子、打印机设备)。像内存、扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待这种资源)。
(2)不剥夺条件:进程所获得的资源在未使用完之前,不能由其他进程强行夺走,只能主动释放。
(3)请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程被阻塞,但又对自己已有的资源保持不放。
(4)循环等待条件:存在一种进程资源的循环等待链,链中的每一个进程己获得的资源同时被下一个进程所请求。
注:发生死锁时一定有循环等待,但是发生循环等待时未必死锁(循环等待是死锁的必要不充分条件)
如果同类资源数大于1,则即使有循环等待,也未必发生死锁。但如果系统中每类资源都只有一个,那循环等待就是死锁的充分必要条件了。
3.什么时候会发生死锁?
(1)对系统资源的竞争。各进程对不可剥夺的资源(如打印机)的竞争可能引起死锁,对可剥夺的资源(CPU)的竞争是不会引起死锁的。
(2)进程推进顺序非法。请求和释放资源的顺序不当,也同样会导致死锁。例如,并发执行的进程P1、P2分别申请并占有了资源R1、R2,之后进程P1又紧接着申请资源R2,而进程P2又申请资源R1,两者会因为申请的资源被对方占有而阻塞,从而发生死锁。
(3)信号量的使用不当也会造成死锁。如生产者-消费者问题中,如果实现互斥的P操作在实现同步的P操作之前,就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源)
4.死锁的处理策略
(1)预防死锁
(2)避免死锁
系统安全状态:
就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。
如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们在分配资源之前总是要考虑到最坏的情况。
如果系统处于安全状态,就一定不会发生死锁。如果系统进入不安全状态,就可能发生死锁(处于不安全状态未必就是发生了死锁,但发生死锁时一定是在不安全状态)
所以采用银行家算法:
①检查此次申请是否超过了之前声明的最大需求数
②检查此时系统剩余的可用资源是否还能满足这次请求
③试探着分配,更改各数据结构
④用安全性算法检查此次分配是否会导致系统进入不安全状态
(3)死锁的检测和解除