操作系统 第二章

第二章笔记只写了一部分,我会上传一部分照片之后会从课件上拷贝一部分当做笔记;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
二、进程控制与并发
进程之间的亲属关系
系统中运行的进程并不都是孤立的,有的进程运行后,会调用其他进程来执行,这样就组成了进程间的父子关系。
1、进程的创建
(1) 申请空白PCB
(2) 为新进程分配资源
主要是内存资源的处理
(3) 初始化进程控制块
标识符(包括父进程的)、程序计数器指向程序入口地址,就绪态、优先级等信息的填写。
(4) 将新进程插入就绪队列
上述过程很关键,不能被打断!!!
原语是由若干指令构成的原子操作过程,作为整体实现功能,不可被打断。
2.进程的终止
正常结束
异常结束
外界干预
过程
(1) 根据进程标示符,检索出该进程PCB,读其状态。
*IF 执行态,立即终止该进程,置调度标志为真,指示重新进行调度。
*IF 有子孙进程,亦应予以终止,以防成为不可控进程。
(2) 归还全部资源至其父进程或系统。
(3) 将该进程PCB从所在队列或链表中移出。
3.进程的阻塞与唤醒
1)引起进程阻塞和唤醒的事件
请求系统服务的满足情况
启动某种需等待(I/O)操作
合作需要的新数据尚未到达
执行某功能的进程暂时无新工作可做(如发送数据进程)
2)阻塞和唤醒过程
由进程调用阻塞原语阻塞自己,是主动行为:
(1)将PCB中的状态改为阻塞
(2)该PCB加入到阻塞队列中
(3)转进程调度,将处理机分配给另一进程
(4)进行进程切换,即根据两切换进程的PCB,保护与重新设置处理机状态
4.进程的挂起与激活
挂起原语将指定进程或阻塞进程挂起。
(1)检查被挂起进程的状态,活动就绪则改为静止就绪,活动阻塞则改为静止阻塞
(2)将该PCB复制到内存(方便检查)/外存(对换)指定区域
(3)若挂起的进程是执行态,则需重新进行进程调度。
关于调度
进程控制中,状态转换和调度密切相关。
运行态进程的改变必然产生调度行为
只要产生新就绪态进程,就需考虑调度策略
只要是采用抢占式调度,要检查新就绪进程是否可抢占CPU,引起新的调度。
2.3 进程同步
两种制约关系:
间接相互制约关系:主要源于资源共享,表现为
进程A—打印机资源—进程B(互斥)
直接相互制约关系:主要源于进程合作,表现为
进程A写缓冲—进程B读缓冲(有序)
1)进程同步的主要任务:
使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。
2)临界资源
一次仅允许一个进程使用的资源。
了解生产者与消费者的问题(课本)
理解同步
互斥:在操作系统中,当一个进程进入临界区使用临界资源时,另一个进程必须等待,直到占用临界资源的进程退出临界区,我们称进程之间的这种相互制约关系为“互斥”。
同步:多个相互合作的进程,在一些关键点上可能需要互相等待或互相交换信息,这种相互制约关系称为进程同步关系。可理解为“有序”。
如:生产和消费的“有序”关系靠对counter的正确判断达到,而对counter的修改必须“互斥”修改。
3)临界区
每个进程中访问临界资源的那段代码叫临界区。
为了正确同步,对临界区的代码要增加控制

进入区:对欲访问的临界资源进行检。若此刻未被访问,设正在访问的标志
临界区:访问临界资源的代码。
退出区:将正在访问的标志恢复为未被访问的标志
剩余区:其余部分

4)同步机制应遵循的规则
实现互斥的方法应符合如下每条原则
空闲让进:资源使用最基本原则
忙则等待:保证互斥
有限等待:合适时被唤醒防止死等
让权等待:能主动释放CPU防止忙等
同步控制的关键
主要涉及”判断”和”修改标志”操作
不应被打断(原语,OS核心态运行)
如何制定一种写法,使标志的使用适用于各种具体应用情况?
硬件同步机制
许多计算机提供一些特殊的硬件指令,允许对一个字中的内容进行检测和修正,或对两个字的内容进行交换。利用这些特殊指令解决临界区问题。
进入临界区往往跟其标志有关,可将标志看做一个锁,“锁开”进入并关锁,“锁关”必须等待,初始时锁是打开的。
①关中断
进入锁测试前关闭中断,直到完成锁测试并上锁后才能打开中断。进程在临界区执行期间,系统不响应中断,从而不引发调度。
缺点:
滥用风险
关中断时间过长会影响效率,限制CPU交叉执行能力
不适用于多CPU系统

2.信号量机制
1) 整型信号量
最初的信号量机制,两个原子操作对一个共享整型量进行操作。
信号量定义为一个整型量;
根据初始情况赋相应的值;
仅能通过两个原子操作来访问。
P操作 wait(S):
While S<=0 do no-op;
S:=S-1;
V操作 signal(S):
S:=S+1;
2)记录型信号量
整型信号量符合“有限等待”原则
signal释放资源后,当CPU被分配给等待进程后,等待进程仍可继续执行,可以符合“有限等待”。
但整型信号量不符合“让权等待”原则
整型信号量的wait操作,当s ≤0时,当前进程会占着CPU不断测试;
信号量原语不能被打断,这个占有CPU的进程会一直不断的占据CPU循环下去,陷入忙等。
改进:条件不符时应能够主动放弃CPU
不仅要有值的处理,还有队列的处理。
此时形成记录型数据结构,包括两部分:
整型变量value(代表资源数目)
进程链表L(链接所有等待进程):
代码描述:
type Semaphore=record
value:integer;
L:list of PCB;
end;
操作:S.Value,S.L
Value>0,表示当前可用资源的数量;
Value≤0,其绝对值表示等待使用该资源的进程数,即在该信号量队列上排队
3)信号量的基本应用
实现进程互斥
实现进程间的前趋关系(有序)
互斥信号量注意点:
互斥信号量mutex初值为1;
每个进程中将临界区代码置于P(mutex)和V(mutex)原语之间
必须成对使用P和V原语(在同一进程中),不能次序错误、重复或遗漏:
遗漏P原语则不能保证互斥访问
遗漏V原语则不能在使用临界资源之后将其释放(给其他等待的进程);
控制同步顺序的注意点
信号量值为0的点是限制的关键所在;
成对使用P和V原语(在有先后关系的两个进程中),不能次序错误、重复或遗漏,否则同步顺序出错。
4)AND型信号量
出现原因:一些应用往往需要两个或多个共享资源,而不是前述的一个资源。进程同时要求的共享资源越多,发生死锁可能性越大。
解决思想:
一次性分配给进程所需资源,用完一起释放。Wait操作时对它所有需要的资源都要判断,有AND条件,故称“AND同步”、“同时wait”
5)信号量集
引入原因:
每次只能获得或释放一个单位的资源,低效;
某些时候资源分配有下限的限制;
修改:在大于可分配设置的下界值t前提下,每次可分配d个。

信号量题目做题一般方法:
分析问题,找出同步、互斥关系
根据资源设置信号量变量
写出代码过程,并注意P、V操作的位置
检查代码,模拟机器运行,体验信号量的变化和程序运行过程是否正确。

信号量机制的不足:
信号量的控制分布在多个进程中
正确性分析困难;
分散的P、V操作:易出错,使用不当可能导致死锁。
修改、维护困难:易读性差,任一修改都可能影响全局;测试期间发现错误困难,即使发现错误也不容易定位出错位置。
管程(monitor)机制

1.管程的组成
一组局部变量
对局部变量操作的一组过程
对局部变量进行初始化的语句。
(联想面向对象中的类)
2.管程特点
任何进程只能通过调用管程提供的过程入口才能进入管程访问共享数据;
就如同使用临界资源,就要先通过其信号量的申请。
任何时刻,仅允许一个进程在管程中执行某个内部过程。
管程如何实现同步?
对共享变量互斥操作:
管程的特点直接实现了该要求,进程一次一个进入管程调用内部过程操作共享变量。
管程的互斥访问完全由编译程序在编译时自动添上,无须程序员关心,能保证正确。
操作的同步控制:
靠条件变量的操作管理实现。
进入管程但不能获取资源操作的过程将阻塞,并在满足条件时被唤醒执行。
3.条件变量
主要作用就是进程同步的阻塞和唤醒控制)
局部于管程的变量有两种:
普通变量
条件变量(用于控制进程阻塞和唤醒)
类似信号量变量,但不取具体值;相当于每个阻塞队列的队列指针。
对条件变量的操作需结合对普通变量的条件判断,从而控制进程状态。
关于条件变量的操作
x.wait将执行进程挂到x对应的等待队列上;
x.signal唤醒x相应的等待队列上的一个进程。
管程的优点
保证进程互斥地访问共享变量,并方便地阻塞和唤醒进程。管程可以以函数库的形式实现。相比之下,管程比信号量好控制。
管程可增强模块的独立性:系统按资源管理的观点分解成若干模块,用数据表示抽象系统资源,使同步操作相对集中,从而增加了模块的相对独立性
引入管程可提高代码的可读性,便于修改和维护,正确性易于保证:采用集中式同步机制。一个操作系统或并发程序由若干个这样的模块所构成,一个模块通常较短,模块之间关系清晰。
管程的缺点
大多数常用的编程语言中没有实现管程,如果某种语言本身不支持管程,那么加入管程是很困难的。
虽然大多数编程语言也没有实现信号量,但可将P、V操作作为一个独立的子例程或操作系统的管理程序调用加入。
2.6 进程通信
进程通信是指进程之间的信息交换。
一、低级通信——进程之间的互斥和同步
信号量机制是有效的同步工具,但作为通信工具缺点如下:
(1)效率低(通信量少)
(2)通信对用户不透明(程序员实现,操作系统只提供共享存储器供代码操作)
二、高级进程通信
用户直接利用操作系统提供的一组通信命令,高效地传送大量数据的通信方式。
操作系统隐藏了进程通信的细节,对用户透明,减少了通信程序编制上的复杂性。
高级通信机制可归结为四大类
1).共享存储器系统(操作存储区方式)
2).消息传递系统(发–收方式)
3).管道通信(中间文件方式)
4).Client-Server system
2.消息传递通信的实现方法
1)直接通信方式
发送进程利用OS所提供的发送命令(原语),直接把消息发送给目标进程。此时,发送进程和接收进程都以显式方式提供对方的标识符。通常利用系统通信命令(原语):
Send(Receiver, message);
Receive(Sender, message);
2)间接通信方式
基于共享数据结构的实体用来暂存发送给目标进程的消息;接收进程则从该实体中,取出对方发送给自己的消息。通常把这种实体称为信箱。
消息在信箱中可以安全地保存,只允许核准的目标用户随时读取。既可实时通信,又可非实时通信。
3.消息传递系统的实现
1).通信链路的建立
计算机网络环境下,用原语显式建立/拆除链路
单机系统只须利用系统原语,进程间链路由系统自动管理。
2).消息格式
单机系统,发送与接收进程在同一台机器,环境相同故格式简单;
网络环境下,受不同目标机器的环境和长距离信息传输等因素的影响,消息格式较复杂,消息常是“大头+正文”
3).同步方式(如何控制发送和接收的状态)
即考虑平时闲着,还是平时忙碌?
发送进程阻塞、接收进程阻塞(无缓冲紧密同步)
发送进程不阻塞、接收进程阻塞(服务器程序)
发送进程和接收进程均不阻塞(缓冲队列)
4.消息缓冲队列通信机制
美国Hansan提出,在RC 4000系统上实现。后被广泛应用于本地进程通信。
1).不需管理链路
2).定义简单数据结构(亦即消息格式)
type message buffer = record
sender; 发送者进程标识符
size; 消息长度
text; 消息正文
next; 指向下一消息缓冲区的指针
end
3).实现发送和接收的操作原语
发送原语:
procedure send(receiver, a)
begin
getbuf(a.size, i); 根据a.size申请缓冲区
i.sender :=a.sender; 将发送区a中的信息复制到 i
i.size :=a.size;
i.text :=a.text;
i.next :=0;
获取接收进程内部标识符
getid(PCB set, receiver, j);
insert(j.mq, i); 将消息缓冲区插入目标消息队列
end
接收原语:
procedure receive(b)
begin
j:=internal name; j为接收进程内部标识符
remove(j.mq, i); 将消息队列中的第i个消息移出
b.sender :=i.sender;
b.size :=i.size; 将消息缓冲区i中的信息
b.text :=i.text; 复制到接收区b
end
认识线程
1.线程的引入
多道程序管理:追求效率的目的下实现“并发”

并发性与效率的讨论
并发进程数量不宜过多,切换频率不宜过高。
限制并发程度问题所在:进程实体信息量大,对进程的管理操作越多,与运行时间的比值就越大,运行效率就低。

提高并发效率,节约时空开销
以进程为单位分配资源
将进程划分为多个功能单位调度执行。
2.线程的属性
多线程OS中,一个进程包括多个线程,每个线程都是利用CPU的基本单位。
轻型实体:只需一点必不可少的、能保证独立运行的资源。(TCB)
独立调度和分派的基本单位:调度切换迅速且开销小。
可并发执行
共享进程资源:同进程中的线程可共享相同的进程地址空间、已打开文件、信号量机构等。
3.线程的信息
状态参数
标识符、运行状态、优先级、寄存器状态、堆栈、专有存储器、信号屏蔽等。
运行状态
执行、就绪、阻塞
4. 线程的创建和终止
在多线程OS中,应用程序启动时,通常只有一个线程(初始化线程)在执行,它根据需要再创建若干线程。
创建新线程
利用线程创建函数(或系统调用),提供相应参数。线程创建函数执行完后,返回一个线程标识符供以后使用。
线程被终止:
不立即释放资源,只有当进程中的其它线程执行分离函数后,资源才分离出来能被其它线程利用。
被终止而未释放资源的线程仍可被需要它的线程调用,使其重新恢复运行。
多线程的应用
一个应用程序有多个任务或功能需要同时进行处理,就最适合多线程机制。
5.多线程系统中的进程
进程只是用于分配系统资源
包括多个线程
不是执行实体,线程在进程范围内作为执行实体。
线程与进程的比较
调度:线程作为CPU调度的基本单位,而进程只作为其它资源分配单位。
并发性:进程之间可以并发,实质上是不同进程中的两个线程并发。一个进程的多个线程之间亦可并发。
拥有资源:进程间资源相互独立;同一进程的各线程间共享。某进程内的线程在其它进程不可见
系统开销:线程上下文切换在同进程环境下上下文切换要快得多。因为同进程内线程间共享内存地址和打开的文件资源;
6.线程的管理
同步和通信机制
1)互斥锁
比较简单的,控制线程互斥访问资源;
适用于高频度使用的关键共享数据和程序段;
unlock和lock两个锁操作原语;
2)条件变量
与互斥锁一起使用
锁保证互斥进入临界区,但利用条件变量使线程阻塞
注意不满足条件时,wait条件变量:
释放互斥锁
进程阻塞在条件变量指向队列中
被唤醒后要重新再设互斥锁
3)信号量
私用信号量(private samephore)
用于同进程的线程间同步,数据结构存放在应用程序的地址空间。属于特定进程,OS感知不到其存在。
公用信号量(public samephore)
用于不同进程间或不同进程中线程的同步,数据结构由OS管理,存放在受保护的系统存储区。
互斥锁是为了上锁而优化的;条件变量是为了等待而优化的;信号灯即可用于上锁,也可用于等待,因而可能导致更多的开销和更高的复杂性。
三种机制适用逐渐复杂的同步情况
二、线程的实现方式
1.内核线程KST(kernel-level thread)
依赖于内核,利用系统调用由OS内核在内核空间完成创建、撤消、切换等线程工作。
时间片分配给线程,所以多线程的进程获得更多CPU时间。
KST优缺点
多处理器系统下可实现多线程并行
一个线程发起系统调用而阻塞,不会影响其它线程的运行
线程切换开销远小于进程切换
内核本身也采用多线程技术可提高系统执行速度和效率
2.用户线程ULT(user-level thread)
无须利用系统调用,不依赖于OS核心。进程利用线程库函数创建、同步、调度和管理控制用户线程。
调度由应用软件内部进行,通常采用非抢先式和更简单的规则,也无需用户态/核心态切换,速度比kst快。
ULT优缺点
用户线程的维护由应用进程完成;内核不了解用户线程的存在;线程切换不需要内核特权;
用户线程调度算法可针对应用优化;
多线程的实现与平台无关
一旦系统调用引起进程阻塞,则整个进程的所有线程都不能执行
以进程为单位分配cpu,所有在多处理器系统中没有优势
BAD:
用户态运行线程,调度和管理线程则是内核态。模式的切换开销大。
3.组合方式
内核支持多KST线程的管理,同时也允许用户应用程序级的线程管理。
具体实现
内核支持的线程直接利用系统调用,线程控制很简单
给创建的新进程分配一个任务数据区PTDA,存放其线程的TCB
信息保存在内核空间中
操作TCB控制线程调度和切换,花费较小

用户级线程需借助某种形式的中间系统取得内核服务,用户程序复杂
运行时系统:管理和控制线程的函数/过程集合。
内核控制线程,轻型进程LWP

Runtime System
所有函数驻留在用户空间上
线程切换由切换过程实现,线程的CPU状态保存在自己的堆栈中,切换不需要转入内核态执行
根本上操作系统资源还是要由内核做。用户线程的所有要求给了运行时系统,由它通过相应的系统调用获得系统资源。

轻权进程(LightWeight Process)
每个轻权进程由一个单独的内核线程来支持。
用户级线程只要连接到一个LWP,就可使用系统调用(如文件读写时,先“捆绑(bound)”在一个LWP上)
永久捆绑:一个LWP固定被一个用户级线程占用,该LWP移到LWP池之外
临时捆绑:从LWP池中临时分配一个未被占用的LWP
在使用系统调用时,如果所有LWP已被其他用户级线程所占用(捆绑),则该线程阻塞直到有可用的LWP--例如6个用户级线程,而LWP池中有4个LWP
如果LWP执行系统调用时阻塞(如read()调用),则当前捆绑在LWP上的用户级线程也阻塞。

猜你喜欢

转载自blog.csdn.net/qq_40066640/article/details/83151638