第二章 进程和线程

操作系统的运行机制和体系结构

image-20210621133052742

运行机制:

image-20210621133205075

image-20210621133240636

image-20210621133358680

image-20210621133443089

操作系统的内核:

image-20210621133833974

内核是计算机上配置的底层软件,是操作系统最基本、最核心的部分

实现操作系统内核功能的那些程序就是内核程序

image-20210621134152666

操作系统的体系结构:大内核、微内核

image-20210621134420784

image-20210621134509294

中断和异常

image-20210621134753614

中断机制的诞生解决程序串行的问题。

image-20210621134901836

image-20210621134909943

中断的概念和作用:

image-20210621135409198

image-20210621135521490

由于操作系统的管理工作(如进程切换、分配I/O设备等)需要使用特权指令,因此CPU要从用户态转为核心态(使用中断,中断是用户态切换到核心态的唯一途径

image-20210621135736733

中断的分类

image-20210621140056097

另一种分类:

image-20210621140131314

外中断的处理过程

image-20210621140332382

步骤:

image-20210621140349552

系统调用

操作系统作为用户和计算机硬件之间的接口,需要向上提供一些简单易用的服务。主要包括命令接口程序接口。其中,程序接口由一组系统调用组成。

系统调用是操作系统提供给应用程序(程序员/编程人员)使用的接口。

image-20210621141329811

在用户程序中,凡是与资源有关的操作(存储分配、I/O操作),都必须通过系统调用的方式向操作系统提出服务请求,由操作系统代为完成。

可以保证系统的稳定性和安全性,防止用户进行非法操作。

image-20210621141323142

image-20210621141408599

系统调用与库函数的区别:

image-20210621141635957

image-20210621141702594

系统调用的过程:

image-20210621142218883

int指令(陷入指令),使其进入核心态

image-20210621142244614

陷入指令是在用户态执行的,执行后立即引发一个内中断,从而CPU进入核心态

image-20210621142507364

系统调用会使处理器从用户态进入核心态。

进程

程序:是一个指令序列

早期计算机只支持单道程序;

image-20210621151213894

引入多道程序技术;

image-20210621151143934

image-20210621151231882

组成:

进程实体(一般也称为进程):PCB、程序段、数据段三部分构成。

进程:是进程实体的运行过程。是系统进行资源分配和调度的一个独立单位。

**PCB是进程存在的唯一标志。**用来描述进程的各种信息。

进程:是一个程序的执行过程,具有“动态性”。

image-20210621152026629

进程标识符PID:

image-20210621151958185

image-20210621152115320

组织方式:

image-20210621152320721

链接方式:

image-20210621152449581

索引方式:

image-20210621152519854

特征:

动态性、并发性、独立性、异步性、结构性。

image-20210621152755055

image-20210621153052834

状态:

运行态,就绪态,阻塞态;

image-20210621162015714

创建态,终止态;

image-20210621162032590

简易理解:

image-20210621162352072

状态的转换:

image-20210621162419168

挂起态和七状态模型:

image-20210622083745992

image-20210622083825412

进程控制

用“原语”实现;就是要实现进程状态的转换。

原语是一种特殊的程序。

原语,一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断。

image-20210621162520460

image-20210621164457075

image-20210621163940219

关/开中断指令是只允许在核心态下的特权指令。

相关的原语:

原语都会做:1、更新PCB中的信息 2、将PCB插入合适的队列 3、分配/回收资源

创建原语、终止原语、阻塞原语、唤醒原语、切换原语

image-20210621164732235

进程通信

image-20210621165356737

共享存储:

image-20210621165558568

image-20210621165619567

image-20210621165624742

管道通信:

image-20210621165703180

采用半双工通信

image-20210621165829163

要实现双向通信需要有两个管道;

管道只有在写满时,才能被读;只有在空时才能被写;

消息传递:

进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息"两个原语进行数据交换。

image-20210621170213585

image-20210621170233541

线程

image-20210621182705794

线程:是一个基本的CPU执行单元,也是程序执行流的最小单位。(轻量级进程)

提升了系统的并度,减少了系统开销;

image-20210621190752261

image-20210621190819493

image-20210621190832822

属性:

image-20210621191215453

实现方式:

用户级线程

image-20210621191559037

用户能够看到线程,操作系统看到的只是进程。

内核级线程:

image-20210621191735535

image-20210621191748013

在同时支持用户级线程和内核级线程的系统中,可采用二者组合的方式:

image-20210621192016121

内核级线程才是处理机分配的单位。

多线程模型

在同时支持用户级线程和内核级线程的系统中,由几个用户级线程映射道几个内核级线程的问题引出了"多线程模型"

多对一模型:

image-20210621193321878

image-20210621193350623

一对一模型:

image-20210621193530473

image-20210621193542691

多对多模型:

image-20210621193608667

image-20210621193616990

注:

image-20210621194118399

进程同步、互斥

回顾:

  • 进程具有异步性,指各并发执行的进程以各自独立的、不可预知的速度向前推进。

  • 进程同步就是为了解决进程异步性的问题。

同步(直接制约关系):指为完成某种任务而建立的两个或多个进程,因为需要在某些位置上协调它们的工作次序而产生的制约关系。(直接制约关系源于它们之间的相互合作)

建议理解:同步就是让进程有工作次序

进程互斥(间接制约关系):

指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。

image-20210622150522171

实现对临界资源的互斥访问,同时保证系统整体性能,需要遵循以下原则:

1、空闲让进:临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区。

2、忙则等待:当已有进程进入临界区时,其他试图进入临界区的几次呢必须等待。

3、有限等待:对请求访问的进程,应保证能在有限时间内进入临界区(防止饥饿)

4、让权等待:进程不能进入临界区时,应立即释放处理机

进程互斥的软件实现方法

image-20210622151435160

单标志法

思想:两个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。

image-20210622161401819

image-20210622161443413

image-20210622161446292

只能P0->P1->P0->P1轮流访问。

存在问题:违背了“空闲让进”原则

双标志先检测法

思想:

image-20210622161750812

先“检查“后上锁。

image-20210622161804457

image-20210622161812631

image-20210622161910262

image-20210622161954103

双标志后检测法:

先”上锁“后”检查“

image-20210622162308406

image-20210622162341623

违背了”空闲让进“和”有限等待“原则,会产生”饥饿“现象。

Peterson算法

”孔融让梨“,主动让对方先使用临界区。

image-20210622162544717

image-20210622162712532

image-20210622162802754

进程互斥的硬件实现方法

image-20210622163233872

中断屏蔽方法:

利用”开/关中断指令“实现

image-20210622171337075

优点:简单高校

缺点:不适用于多处理机;只适用于操作系统内核进程,不适合于用户进程(因为中断指令只能运行内核态)

TestAndSet指令

image-20210622171744653

image-20210622171832175

image-20210622171840881

优点:实现简单;适用于多处理机环境

缺点:不满足”让权等待“原则。

Swap指令

image-20210622172355445

image-20210622172555701

优点:简单

缺点:不满足"让权等待"原则。

信号量机制

image-20210622172823656

用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。

信号量是一个变量(可以是整数,或者是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量

image-20210622174453407

image-20210622174713873

整型信号量

image-20210622175327407

存在问题:不满足”让权等待“原则,会发生”忙等“。

记录型信号量

image-20210622175839664

image-20210622175945956

image-20210622180013132

signal原语中,S.value<=0说明还有进程正在等待分配资源(有资源处于等待队列),因为wait是先执行了S.value–后进入挂起状态。有进程等待所以需要执行wekeup原语。

image-20210622181012310

遵循了”让权等待“原则。(进程自我阻塞就是主动放弃处理机)

注:考试中P(S),V(S)操作默认S为记录型信号量

实现进程互斥

互斥信号量mutex

image-20210622185807219

信号量的声明可以自己定义。

image-20210622185837116

image-20210622185912155

要使用不同的临界资源就定义新的互斥信号量

image-20210622190044877

实现进程同步

image-20210622192753816

image-20210622192855237

分析:

image-20210622193155277

实现前驱关系

要求代码按如下前驱图顺序去执行:

image-20210623081549048

类似于同步操作。

image-20210623081636903

生产者-消费者问题

image-20210623082030515

image-20210623082159107

分析思路:

image-20210623082950587

image-20210704195951113

image-20210623083227193

semaphore mutex=1;//互斥信号量,实现对缓冲区的互斥访问
semaphore empty=n;//同步信号量,表示空闲缓冲区的数量
semaphore full=0;//同步信号量,表示产品的数量,也即非空缓冲区的数量

//生产者
producer(){
    while(1)
    {
        生产一个产品;
        P(empty);
        P(mutex);
        把产品放入缓冲区;
        V(mutex);
        V(full);
    }
}
//消费者
consumer(){
    while(1)
    {
        P(full):
        P(mutex);
        从缓冲区取走一个产品;
        V(mutex);
        V(empty);
        使用产品;
    }
}

注:

  • 实现互斥是在同一进程中进行一对PV操作;

  • 实现两进程的同步关系,是在其中一个进程中执行P,另一进程中执行V

  • 两个相邻的P操作不能互换,实现互斥的P操作一定要在实现同步的P操作之后。

  • V操作不会导致进程阻塞,两个相邻V操作可以互换

  • 非临界区代码可以放入临界区,但是会降低并发度

多生产者-多消费者问题

image-20210623093859264

image-20210623094013818

image-20210623094105364

代码实现:

image-20210623094138424

image-20210623094202854

image-20210623094221433

吸烟者问题

image-20210623094425483

image-20210623094633262

image-20210623094642254

image-20210623094811019

代码实现:

image-20210623094958343

image-20210623095012702

image-20210623095023255

读者-写者问题

image-20210623095743349

分析题目:

image-20210623095917920

image-20210623103101663

解决:设置互斥变量,使操作P(rw)和count++一气呵成

image-20210623103604209

但还是存在问题;解决:加一个互斥信号量。

image-20210623104005742

这样执行顺序会按序执行;

总体代码:

image-20210623104057867

“写优先”类似于先来先服务,没用真正的写优先

image-20210623104151873

哲学家进餐问题

image-20210623132928184

image-20210623133049172

image-20210623133058820

image-20210623133202569

如何防止死锁:

image-20210623133227900

image-20210623133237615

实现代码:(另一种方式)

image-20210623133427779

image-20210623133504899

哲学家问题关键在于解决死锁;

管程

image-20210623134309282

image-20210623134541050

管程的定义:

image-20210623134621996

即把过程封装起来。

基本特征:

image-20210623134655644

用管程解决生产者消费者问题:

(以下就是管程ProducerConsumer的写法,各有不同)

image-20210623134758368

image-20210623134903430

总结:

image-20210623135142669

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值