操作系统大题复习

磁盘调度算法

一次磁盘读写需要的时间

寻道时间

先来先服务FCFS

优点:公平

缺点:性能差,寻道时间长

最短寻道时间有限SSTF

缺点:可能产生饥饿现象

扫描算法SCAN

优点:不会产生饥饿现象

缺点:响应频率不平均

循环扫描算法C-SCAN

优点:磁道响应频率平均

缺点:平均寻道时间长

多道批处理系统   CPU   I/O

FCFS先来先服务算法、SJF短作业优先、优缺点

处理机调度算法

先来先服务FCFS

(不会导致饥饿)

优点:算法简单,有利于长作业

缺点:平均等待时间波动大,I/O资源和CPU资源的利用率低

短进程优先SPF

优点:平均周转时间和平均带权周转时间小,缩短作业的等待时间,提高系统的吞吐量

缺点:对长进程不利,长时间得不到执行

优先权PSA

优点:体现进程的紧急程度,适合实时系统

缺点:无穷阻塞问题,会导致饥饿

高响应比HRRN

优点:有利于短作业,综合考虑等待时间和运行时间,避免长进程的饥饿问题

缺点:计算响应比,增加系统开销

时间片轮转RR

优点:响应快,公平

缺点:高频率的进程切换,有一定的开销

多级反馈队列

优点:兼顾I/O密集和CPU密集型

缺点:算法复杂

文件系统

系统调用    fwrite()

(1)       在内核栈保存大多数寄存器的内容
(2)       调用所谓系统调用服务例程的相应的C函数来处理系统调用。
(3)       通过ret_from_sys_call(  )函数从系统调用返回(这个函数用汇编语言编写)。
 xyz(  )系统调用对应的服务例程的名字通常是sys_xyz(  ) 
为了把系统调用号与相应的服务例程关联起来,内核利用了一个系统调用表;这个表存放在sys_call_table数组中,有NR_syscalls个表项(通常是256个):第n个表项包含系统调用号为n的服务例程的地址。NR_syscalls宏只是对可实现的系统调用最大个数的静态限制,并不表示实际已实现的系统调用个数。 

1.从用户程序中调用fork
2.在libc库中把fork对应的系统调用号2放入寄存器eax
3.通过int 0x80陷入内核
4.在中断描述表IDT中查到系统调用的入口0x80
5.进入Linux内核的entry_32(64).S文件,从系统调用表sys_call_table中找到sys_fork的入口地址
6.执行fork.c中的do_fork代码
7 通过iret或者sysiret返回

物理地址的转化

请求分页存储管理

页面置换算法

最佳置换算法OPT

先进先出置换算法FIFO

最近最久未使用置换算法LRU

CLOCK置换算法

磁盘读写----最短寻道时间算法、扫描算法

进程状态转化

银行家算法

进程WorkAllocationNeedW+AFinish
P13 3 22 0 01 2 25 3 2T
P35 3 22 1 10 1 17 4 3T
P47 4 30 0 24 3 17 4 5T
P27 4 53 0 26 0 010 4 7T
P010 7 40 1 07 4 310 5 7T

(1)安全

(2)P1请求Request(1,0,2)小于Need(1,2,2),小于Available(3,3,2)

假设分配,找到安全序列P1、P3、P4、P0、P4

Available=Available-Request

Need=Need-Request

Allocation=Allocation+Requesr

Work=Work-Request

(3)P4请求Request(3,3,0)>Available  阻塞等待

(4)P0请求Request(1,0,2)小于Need(1,2,2),小于Available(3,3,2)

Available=(3,3,2)-(1,0,2)=(2,1,0)不满足任何进程的需要,找不到安全序列,P0请求被拒绝,P0阻塞,资源不予分配

安全序列

死锁

四个必要条件:互斥条件、请求和保持条件、不可剥夺条件、循环等待条件

死锁产生的原因:并发进程/线程的调度推进顺序不恰当

竞争非剥夺性资源、临时性资源可能产生死锁

死锁的处理策略:预防策略、避免策略、检测与解除、鸵鸟策略

破坏互斥条件---互斥虚拟为共享

破坏不接剥夺条件----主动放弃

破坏请求和保持条件----一次申请所有资源 

破坏循环等待条件---资源有序使用

可变分区分配

首次适配算法

循环首次适配算法

最佳适配算法

最差适配算法

I/O层次结构

用户层I/O软件:实现与用户交互的接口,用户可直接调用在用户层提供的、与I/O操作有关的库函数,对设备进行操作。(按出现问题)
设备独立性软件:设备独立性也称设备无关性,使得应用程序独立于具体使用的物理设备,为了实现设备独立性,必须再在驱动程序之上设置一层设备独立性软件。优点 是方便用户,改善设备利用率,提高系统的可扩展性和可适应性。总的来说,设备独立性软件的主要功能可分以为以下两个方面:1、执行所有设备的公有操作;2、向用户层(或文件层)提供统一接口。
设备驱动程序:处于次底层,是进程和控制器之间的通信程序,其将上层发来的抽象I/O请求,转换为对I/O设备的具体命令和参数,并把它装入到设备控制其中的命令和参数寄存器中。负责具体实现系统对设备发出的操作指令,驱动 I/O设备工作的驱动程序。
中断处理程序:用于保存被中断进程的CPU环境,转入相应的中断处理程序进行处理,处理完并恢复被中断进程的现场后,返回到被中断进程。
 

优点:从位示图中很容易找到一个或一组相邻接的空闲盘块,占用空间少,节省许多磁盘的启动操作

 DMA方式的进入:为了适应一次传送大量数据的应用要求,以及尽量减少CPU对高速外设的干预。
      与“中断驱动方式”相比,DMA(Direct Memory Access,直接存储器存取。主要用于块设备的I/O控制)有这样几个改进:

(1) 数据传送的单位是块,不再是一个字一个字的传送。
(2) 数据的流向是从设备直接放入内存,或者直接从内存到设备,不再需要CPU干预。
(3) 仅在一个块或多个块的开始和结束时,才需要CPU干预。

当我们在用户程序中调用read()函数时,陷入内核空间,实际上要通过内核的copy_to_user()函数把内核空间缓冲区中的数据拷贝到用户空间的缓冲区,反之,当我们调用write()函数时,内核通过调用copy_from_user()函数把用户空间的数据拷贝到内核缓冲区。

fd

文件描述符是用来描述打开的文件的。在内核中每个进程用一个files_struct结构来记录文件描述符的使用情况,这个files_struct结构称为用户打开文件表,它是进程的私有数据。对于在数组中有入口地址的每个文件来说,数组的索引就是文件描述符。通常,数组的第0,1,2三个下标分表表示三个标准的输入,输出和错误文件,3分配给新打开的文件(如图)。在这里强调,每个打开的文件,在内核 中都有file对象,每一个文件描述符都是指向file结构的。
 

read()、write()

文件系统

索引节点

文件系统需要将文件的磁盘索引结点载入内存,以便操作系统可以通过内存索引结点管理这个文件,通常使用open操作实现

如图所示,以Unix文件系统为例,使用线性检索目录的方式,介绍检索mbox文件的目录检索过程,其中(按)1、2、3部分是目录内容,1是根目录的内容、2是目录usr的内容、3是目录406的内容。
具体的检索过程是:
(1)操作系统首先找到根目录,根目录位于磁盘分区的固定位置,所以OS可以轻松的找到该目录。
(按) 查找根目录内容,发现usr对应的磁盘索引结点node是6号,从文件系统概述那节我们了解到,文件系统从创建起来的时候,操作系统就知道所有文件的磁盘FCB和磁盘inode的物理地址,因此很容找到usr目录的inode结点。
(2)(按)找到6号inode,读取内容,查询发现/usr目录内容存放在132号物理块中。
(3)(按)读取132号物理块内容,查询发现/usr/ast的inode编号为26。
(4)(按)接着找到26号inode,读取内容,/usr/ast目录内容存放在块406中。
(5)(按)找到406号物理块,读取内容,/usr/ast/mbox的磁盘inode编号是60。
至此,内核完成了按名找到mbox的FCB和inode的目标。
 

文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 扇区组成一个 block。
文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的权限,文件的创建日期、文件的大小,文件数据块的位置等等。这种储存文件元信息的区域就叫做inode

读者写者

信号量,初值

伪代码

单生产者--消费者


 

首先定义信号量space和prod,然后在main函数中对这两个信号量进行初始化,接着依次创建生产者线程和消费者线程。
      生产者线程为无穷循环,每放一个产品之前,先要申请存储位置资源,因此对信号量space进行sem_wait操作,放入产品后,新生成一个产品资源,故对信号量prod进行sem_post操作。消费者线程在取产品前,先对信号量prod进行sem_wait操作,申请产品资源,成功后取走产品,并通过sem_post(&space)释放一个缓冲区资源。为了大家查看生产者及消费者线程的运行效果,在这里我们使用printf语句分别模拟放产品和取产品。
      分析该程序,不难看出在信号量的控制下,生产者线程与消费者线程在执行时,按照“生产者放1个产品->消费者取1个产品->生产者再放1个产品->……”这样的顺序有序执行,很好的解决了生产者与消费者间的同步问题。

 先定义表示缓冲区大小的常量N,假设为10;然后定义信号量space和prod;另外,定义存储产品的数组Buffer,并定义循环队列的队头指针out和队尾指针in。main函数中,将信号量space初始化为N,其他代码跟前面一样。
       生产者线程和消费者线程跟前面总体一致。生产者在放产品前先对信号量space进行sem_wait操作,申请存储位置资源,成功后将产品放到队尾in的位置,并修改队尾指针,完成后对信号量prod进行sem_post操作释放一个产品资源。消费者线程取产品依然需要通过sem_wait(&prod)操作获取一个产品资源,成功后从队头out的位置取产品,并修改队头指针,最后通过sem_post(&space)释放一个缓冲区资源。
      该程序和单缓冲区程序的最大差别在于,生产者线程可以连续生产最多N个产品放到缓冲区中供消费者消费

 增加表示生产者与消费者个数的常量M,令其为8;增加信号量buf。在main函数中,除增加对信号量buf进行初始化外,分别通过循环创建M个生产者和消费者线程。
       生产者线程在放产品前,先通过sem_wait(&space)操作申请存储位置资源,然后再通过sem_wait(&buf)操作获取缓冲区的控制权,成功后将产品放到队尾的位置并修改队尾指针,完成后在通过sem_post(&prod)释放一个产品资源的同时,并通过sem_post(&buf)释放缓冲区资源。
      与此对应,消费者线程在取产品前,先通过sem_wait(&prod)操作申请产品资源,然后再通过sem_wait(&buf)操作获取缓冲区的控制权,成功后从队头位置取产品并修改队头指针,完成后通过sem_post(&space)释放一个存储位置资源,并通过sem_post(&buf)释放缓冲区资源。
     在信号量buf的控制下,任何时候只能有一个生产者或消费者进入缓冲区存放或者取产品,实现了生产者以及消费者之间对缓冲区的互斥访问。
     大家请注意,在消费者线程中,先通过sem_wait(&prod)申请产品资源,然后再通过sem_wait(&buf)申请缓冲区资源,能否把这两条语句的顺序交换一下呢?
      我们把这两条语句交换一下,分析看看结果是否还正确。假设第1个消费者线程先执行,对buf信号量进行了sem_wait操作后,buf的值从1变为0,资源分配成功,进一步对prod信号量进行sem_wait操作,此时prod的值从0变为-1,消费者线程被阻塞;在此之后,其它消费者线程若执行,也同样会被阻塞。 当第1个生产者线程执行时,虽然对space信号量进行sem_wait操作可以成功,但再对buf进行sem_wait操作时,由于此时buf的值已经小于等于0,减1后buf值小于0,生产者进程被阻塞,其它生产者进程陆续执行后也被阻塞。结果是生产者线程无法获取缓冲区资源存放产品,而消费者线程占据着缓冲区等待产品的到来,最终导致了生产者和消费者线程间发生了死锁,谁也无法继续执行。
       通过这个例子,大家可以看到在使用记录型信号量申请多种临界资源时,必须仔细分析,稍有不慎会导致死锁的发生。

生产者线程在放产品前,先通过Swait(space,buf)操作同时申请存储位置资源和缓冲区资源,成功后将产品放到队尾的位置并修改队尾指针,完成后再通过Ssignal(prod,buf)释放产品资源和缓冲区资源。
      相应的,消费者线程取产品前,先通过Swait(prod,buf)操作申请产品资源和缓冲区资源后,然后从队头取出产品并修改队头指针,完成后通过Ssignal(space,buf)   释放存储位置资源和缓冲区资源。
      使用ADD信号量后,生产者线程及消费者线程一次性申请完所有执行所需要的资源,避免了死锁的发生。

  除存储位置信号量space和产品信号量prod外,新定义队头和队尾信号量sin和sout。在main函数中,依然需要分别对这四个信号量进行初始化,并通过循环创建M个生产者和消费者线程。
      按照前面讲的策略,生产者线程在放产品前,先通过sem_wait(&space)操作申请存储位置资源,然后再通过sem_wait(&sin)操作获取队列尾变量in资源的使用权,成功后将产品放到队尾位置并修改队尾指针,完成后在通过sem_post(&prod)释放一个产品资源的同时,通过sem_post(&sin)释放队尾变量资源。
     与此对应,消费者线程在取产品前,先通过sem_wait(&prod)操作申请产品资源,然后再通过sem_wait(&sout)操作获取队头变量out的控制权,成功后从队头位置取产品并修改队头指针,完成后通过sem_post(&space)释放一个存储位置资源,并通过sem_post(&sout)释放队头变量资源。
      分析该程序,我们可以看到,信号量space和prod的作用和前面单生产者-消费者问题相同,用于实现生产者与消费者之间的同步。另外,在信号量sin的控制下,在同一时刻只能有一个生产者线程访问临界资源in,将产品放到队列末尾位置,并修改队尾指针;相应的,在信号量sout的控制下,在同一时刻也只能有一个消费者线程从队头位置取产品。改进方案的最大优点是,在同一时刻允许一个生产者和一个消费者同时在缓冲区中放产品和取产品,提高了系统的运行效率。
     在优化后的程序里,消费者线程先通过sem_wait(&prod)申请产品资源,然后再通过sem_wait(&sout)申请队列头资源,依然逐次申请了两个不同的资源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Node.js学习(一)

Node.js安装与入门案例: 需求:点击按钮,请求本地目录指定文件的内容,并显示在页面上 刚入门肯定想着直接写相对路径请求指定路径数据就行了,可是会发现不行。 网页运行在浏览器端,通常后续要发布&#xf…

docker部署wg-easy和firefly

Background WireGuard是一种新型的VPN协议,它通过在内核层运行,提供高效、安全、简单和现代的VPN解决方案。wg-easy是一个专为简化 WireGuard VPN配置和管理而设计的工具,提供了界面化的管理,进一步降低WireGuard 的使用门槛,让用户无需深入了…

【C++】STL-stack_queue

目录 1、stack和queue的使用 1.1 最小栈 1.2 栈的弹出和压入序列 1.3 二叉树的层序遍历 2、stack和queue的模拟实现 2.1 适配器 2.2 deque 2.2.1 deque的成员变量 2.2.2 deque的迭代器 2.2.3 deque尾插元素 2.2.4 deque头插元素 2.2.5 下标访问 2.2.6 deque的不足 …

golang结合neo4j实现权限功能设计

neo4j 是非关系型数据库之图形数据库,这里不再赘述。 传统关系数据库基于rbac实现权限, user ---- role ------permission,加上中间表共5张表。 如果再添上部门的概念:用户属于部门,部门拥有 角色,则又多了一层: user-…

数据加密解密和哈希的解析

[S1301]数据的加解密 对提供的原始数据(字符串或者二进制数组)进行加密是数据保护框架体提供的基本功能,接下来我们利用一个简单的控制台程序来演示一下加解密如何实现。数据的加解密均由IDataProtector对象来完成,而该对象由IDa…

Elasticsearch:Runtime fields - 运行时字段(一)

运行时字段(runtime fields)是在查询时计算的字段。运行时字段使你能够: 向现有文档添加字段而无需重新索引数据开始处理数据而无需了解其结构在查询时覆盖索引字段返回的值定义用于特定用途的字段而无需修改底层架构 你可以像访问其他任何…

bash条件判断基础adsawq1`1nn

判断的作用 判断后续操作的提前条件是否满足如果满足执行一种命令不满足则执行另一种指令 条件测试类型: 整型测试字符测试文字测试 整数测试:比较两个整数谁大谁小,是否相等; 二元测试: num1 操作符 num2 -eq: 等于…

uniapp封装虚拟列表滚动组件

uniapp封装虚拟列表滚动组件 这里用到一个列表&#xff0c;然后数据可能有很多很多…&#xff0c;一次性全部渲染到dom上会卡顿&#xff0c;很废性能&#xff0c;于是用了这个虚拟列表就变丝滑很多很多。 组件mosoweInventedList 代码&#xff1a; <!-- 虚拟滚动列表组件&a…

代码随想录Day67(图论 part04)

110.字符串接龙 题目&#xff1a;110. 字符串接龙 (kamacoder.com) 思路&#xff1a;没有思路 答案 import java.util.*;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();String beginStr sc…

华为手机怎么打印文件?

关于华为手机打印的问题&#xff0c;如果您有打印机&#xff0c;并且已经成功和华为手机相连&#xff0c;在解决上就要容易很多。 具体操作如下&#xff1a; 选择文件 文件来源&#xff1a;华为手机上的文件可以来自多个应用&#xff0c;如图库、备忘录、文件管理等&#xf…

20240628模拟赛总结

cf好了 让我们开始 T1 Two Regular Polygons 判断能不能构造出题中要求的正多边形 关键是n%m0 Two Regular Polygons #include<bits/stdc.h> using namespace std; int t; int n,m; int main() {cin>>t;for(int i1;i<t;i){cin>>n>>m;if(n%m0)co…

MySQL——事务ACID原则、脏读、不可重复读、幻读

什么是事务 要么都成功&#xff0c;要么都失败 一一一一一一一 1. SQL执行&#xff1a;A给B转账 A 1000 ---->200 B 200 2. SQL执行&#xff1a;B收到A的钱 A 800 B 400 一一一一一一一 将一组SQL放在一个批次中去执行~ 事务原则&#xff1a;ACI…

学习笔记(linux高级编程)10

IPC 进程间通信 interprocess communicate 三大类&#xff1a; 1、古老的通信方式 无名管道 有名管道 信号 2、IPC对象通信 system v BSD suse fedora kernel.org 消息队列(用的相对少&#xff0c;这里不讨论) 共享内存 信号量集 3、socket通信 网络通信 特…

TF/IDF算法

第1关&#xff1a;去除停用词 任务描述 本关任务&#xff1a;根据本关所学有关停用词的知识&#xff0c;编写使用停用词表去除停用词的程序并通过测试用例。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 停用词的意义&#xff1b; 去除停用词的步骤。 …

浅谈Web性能测试(原创)

一、性能测试不是什么高技术的活&#xff1a; 说到性能测试&#xff0c;很多工作时间较短的新同事或者应届生就很害怕。 为什么害怕&#xff0c;因为感觉无从下手&#xff0c;不知道该做什么、怎么做、做到什么程度&#xff1f; 一听性能测试首先想到的是各种专业的性能测试…

ThingsKit物联网平台功能解析

随着物联网技术的飞速发展&#xff0c;各种物联网平台应运而生&#xff0c;为设备管理和数据集成提供了强大的支持。ThingsKit物联网平台以其全面的功能和灵活的配置&#xff0c;成为行业中的一大亮点。本文将详细解析ThingsKit物联网平台的功能清单&#xff0c;带您深入了解该…

oracle数据库默认表空间详解

文章目录 oracle数据库默认表空间列表 oracle数据库默认表空间列表 系统表空间&#xff08;System Tablespace&#xff09; 系统表空间包含了系统级别的元数据&#xff0c;如数据字典、系统表和存储过程等。例如SYSTEM表空间用于保存数据库的数据字典、PL/SQL程序的源代码和解释…

【C语言】分支(选择)和循环语句

目录 简述选择语句简述if语句单if结构语法格式 if-else结构语法结构 语法结构 循环结构break和continuewhile循环语法结构 for循环语法结构 do while循环语法结构 简述 在c语言中分支和循环语句是极其重要的&#xff0c;就像生活中你难免要做一些判断和循环往复做一些事。 选…

SpringBoot 中的参数校验:构建健壮应用的基石

前言 在开发Web应用时&#xff0c;处理用户输入是不可避免的一环。然而&#xff0c;用户输入往往充满不确定性&#xff0c;可能是格式不正确、类型不匹配&#xff0c;甚至包含恶意内容。为了确保应用的稳定性和安全性&#xff0c;对输入参数进行有效校验显得尤为重要。Spring …