[面试]操作系统

操作系统

什么是操作系统

  • 操作系统(Operating System,简称OS)本质上是运行在计算机上的软件程序 ,是管理计算机硬件与软件资源的程序
  • 操作系统为用户提供一个与系统交互的操作界面 ;
  • 操作系统分内核与外壳(我们可以把外壳理解成围绕着内核的应用程序,而内核可以理解为能直接操作硬件的程序)
  • 内核负责管理系统的进程、内存、设备驱动程序、文件和网络系统等等,决定着系统的性能和稳定性。是连接应用程序和硬件的桥梁

用户态和内核态

  • 用户态(user mode) : 用户态运行的进程或可以直接读取用户程序的数据
  • 系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制

系统调用

  • 设备管理。完成设备的请求或释放,以及设备启动等功能。
  • 文件管理。完成文件的读、写、创建及删除等功能。
  • 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信。完成进程之间的消息传递或信号传递等功能。
  • 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能

进程线程区别

  • 线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助 IPC

需要线程原因

线程状态

进程间通信方式

  • 管道/匿名管道(Pipes)
    • 用于具有亲缘关系的父子进程间或者兄弟进程之间的通信
    • 是只存在于内存的文件
  • 有名管道(Names Pipes)
    • 有名管道严格遵循先进先出(first in first out)
    • 有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信
    • 以磁盘文件形式存在于实际的磁盘介质或者文件系统
  • 信号(Signal)
    信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生
  • 消息队列(Message Queuing)
    • 消息队列是消息链表,存放在内存中并由消息队列标识符标识
    • 消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除
    • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取
    • 消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺
  • 信号量(Semaphores)
    • 信号量是一个计数器,用于多进程对共享数据的访问
    • 信号量的意图在于进程间同步,主要用于解决与同步相关的问题并避免竞争条件。
  • 共享内存(Shared memory)
    • 使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新
    • 这种方式需要依靠某种同步操作,如互斥锁和信号量
    • 可以说这是最有用的进程间通信方式
  • 套接字(Sockets)
  • 此方法主要用于在客户端和服务器之间通过网络进行通信
  • 套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程

线程间的同步方式

线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键的资源使用冲突操作系统一般有下面三种线程同步的方式

互斥量(Mutex)

  • 采用互斥对象机制,只有拥有互斥对象的线程才能访问公共资源的因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问
  • 比如 Java 中的 synchronized 关键词和各种 Lock 都是这种机制
系统调用
  • pthread_mutex_init:初始化互斥锁
  • pthread_mutex_destroy:销毁互斥锁
  • pthread_mutex_lock:以原子操作的方式给一个互斥锁加锁,如果目标互斥锁已经被上锁, pthread_mutex_lock 调用将阻塞,直到该互斥锁的占有者将其解锁。
  • pthread_mutex_unlock:以一个原子操作的方式给一个互斥锁解锁。

信号量(Semphares)

它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量

系统调用

PV操作

  • sem_wait(sem_t *sem):以原子操作的方式将信号量减 1,如果信号量值为 0,则 sem_wait 将被阻塞,直到这个信号量具有非 0 值。
  • sem_post(sem_t *sem):以原子操作将信号量值+1。当信号量大于 0 时,其他正在调用 sem_wait 等待信号量的线程将被

事件(Event)

Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作

管程

  • 使用信号量机制实现的生产者消费者问题需要客户端代码做很多控制,而管程把控制的代码独立出来,不仅不容易出错,也使得客户端代码调用更容易
  • 管程有一个重要特性:在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否则其它进程永远不能使用管程。

操作系统进程调度算法

批处理系统

先到先服务(FCFS)调度算法

从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度。

短作业优先(SJF)的调度算法
  • 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度
  • 短进程优先的调度算法,仅照顾了短进程而忽略了长进程
最短时间优先算法(SRTN)
  • 最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较
  • 如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待

交互式系统

时间片轮转调度算法

时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

多级反馈队列调度算法

  • 多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。
  • 因而它是目前被公认的一种较好的进程调度算法,UNIX操作系统采取的便是这种调度算法。

优先级调度

为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以FCFS方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级

实时系统

操作系统的内存管理

内存管理

  • 负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存)
  • 地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情

几种内存管理机制

块式管理

  • 远古时代的计算机操系统的内存管理方式。将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块
  • 如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片

页式管理

  • 把主存分为大小相等且固定的一页一页的形式,页较小,相对相比于块式管理的划分力度更大,提高了内存利用率,减少了碎片
  • 页式管理通过页表对应逻辑地址和物理地址
  • 页本身是无意义的

段式管理

-段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多 段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等

  • 段式管理通过段表对应逻辑地址和物理地址

段页式管理

  • 结合了段式管理和页式管理的优点,就是把主存先分成若干段,每个段又分成若干页
  • 段页式管理机制中段与段之间以及段的内部的都是离散的

快表和多级页表

快表和多级页表分别解决了页表管理中很重要的两个问题

  • 虚拟地址到物理地址的转换要快
  • 解决虚拟地址空间大,页表也会很大的问题

快表

  • 解决虚拟地址到物理地址的转换,操作系统在页表方案基础之上引入了快表来加速虚拟地址到物理地址的转换
实现
  • 块表可以理解为一种特殊的高速缓冲存储器(Cache)其中的内容是页表的一部分或者全部内容
  • 作为页表的Cache,它的作用与页表相似,但是提高了访问速率,由于采用页表做地址转换,读写内存数据时CPU要访问两次主存。有了快表,有时只要访问一次Cache次主存,这样可加速查找并提高指令执行速度
快表实现地址转换
  • 根据虚拟地址中的页号查快表如果该页在快表中,直接从快表中读取相应的物理地址;
  • 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表
  • 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页

开发中的系统如Redis实现思想和快表十分相似

多级页表

  • 引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中
  • 多级页表属于时间换空间的典型场景

分页机制和分段机制的共同点和区别

共同点

  • 分页机制和分段机制都是为了提高内存利用率,较少内存碎片
  • 页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内存是连续的

区别

  • 页的大小是固定的,由操作系统决定;而段的大小不固定,取决于我们当前运行的程序。
  • 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需要

虚拟内存机制

操作系统程序内存结构

(一个程序本质上都是由 BSS 段、data 段、text 段三个组成的)

-BSS 段(未初始化数据区):通常用来存放程序中未初始化的全局变量和静态变量的一块内 存区域。BSS 段属于静态分配,程序结束后静态变量资源由系统自动释放

  • data段:存放程序中已初始化的全局变量的内存区域
  • text段:存放程序执行代码的一段区域
  • 栈:由编译器自动释放,存放函数的参数值、局部变量等

虚拟地址和物理地址

  • 逻辑地址由操作系统决定
  • 物理地址指的是真实物理内存中地址,内存地址寄存器中的地址。物理地址是内存单元真正的地址

CPU寻址

  • CPU需要将虚拟地址翻译成物理地址,这访问到真实的物理内存
  • CPU中的内存管理单元完成虚拟地址转换为物理地址转换的硬件

虚拟地址空间

隐藏物理地址,避免直接访问可能对操作系统造成伤害以及给同时运行多个程序造成困难

  • 程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的大内存缓冲区
  • 程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。
  • 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存

虚拟内存

虚拟内存的重要意义是它定义了一个连续的虚拟地址空间并且把内存扩展到硬盘空间

  • 虚拟内存可以让程序可以拥有超过系统物理内存大小的可用内存空间
  • 虚拟内存为每个进程提供了私有地址空间,独享主存(每个进程拥有一片连续完整的内存空间)
  • 进程通信可使用虚拟内存贡共享

局部原理性

  • 虚拟内存技术的基础,正是因为程序运行具有局部性原理,才可以只装入部分程序到内存就开始运行
  • 虚拟内存技术实际上就是建立了 “内存一外存”的两级存储器的结构,利用局部性原理实现髙速缓存
时间局限性
  • 如果程序中的某条指令一旦执行,不久以后该指令可能再次执行如果某数据被访问过,不久以后该数据可能再次被访问
  • 产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作
  • 时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现

空间局限性

  • 一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内
  • 因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的
  • 通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现

虚拟内存代价

  • 虚存的管理需要建立很多数据结构,占用额外的内存
  • 虚拟地址到物理地址的转换,增加了指令的执行时间
  • 页面的换入换出需要磁盘 I/O这是很耗时的
  • 如果一页中只有一部分数据,会浪费内存。

虚拟存储器

  • 基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行
  • 由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的
  • 在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序
  • 操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息

这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器

虚拟内存的技术实现

虚拟内存的实现需要建立在离散分配的内存管理方式的基础上

虚拟内存实现基础
  • 一定容量的内存和外存:在载入程序的时候,只需要将程序的一部分装入内存,而将其他部分留在外存,然后程序就可以执行了;
  • 缺页中断:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序;
  • 虚拟地址空间 :逻辑地址到物理地址的变换

虚拟内存的实现有以下三种方式:

请求分页存储管理

建立在基本分页系统基础之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法

请求分段存储管理
请求段页式存储管理

页面置换算法

  • 地址映射过程中,若在页面中发现所要访问的页面不在内存中,则发生缺页中断
  • 缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问。在这个时候,被内存映射的文件实际上成了一个分页交换文件

当发生缺页中断时,若内存中无空闲页面,操作系统就在内存选择一个页面将其移出内存,为需要调入的页面让出空间,用来选择淘汰页的规则叫做页面置换算法

  • OPT页面置换算法(最佳页面置换算法)
  • 理想情况,不可能实现,一般作为衡量其他置换算法的方法
  • FIFO页面置换算法(先进先出页面置换算法)
    总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面进行淘汰。
  • LRU页面置换算法(最近未使用页面置换算法)
    LRU(Least Currently Used)算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间T,当须淘汰一个页面时,选择现有页面中其T值最大的,即最近最久未使用的页面予以淘汰
  • LFU页面置换算法(最少使用页面排序算法)
    LFU(Least Frequently Used)算法会让系统维护一个按最近一次访问时间排序的页面链表,链表首节点是最近刚刚使用过的页面,链表尾节点是最久未使用的页面。访问内存时,找到相应页面,并把它移到链表之首。缺页时,置换链表尾节点的页面。也就是说内存内使用越频繁的页面,被保留的时间也相对越长。

链接

编译系统

Unix系统上由编译器将源文件转换为目标文件过程为

  • 预处理:处理以 # 开头的预处理命令
  • 编译阶段:翻译成汇编文件
  • 汇编阶段:将汇编文件翻译成可重定位目标文件
  • 链接阶段:将可重定位目标文件和 printf.o 等单独预编译好的目标文件进行合并,得到最终的可执行目标文件

目标文件

  • 可执行目标文件:可以直接在内存中执行
  • 可重定位目标文件:可与其它可重定位目标文件在链接阶段合并,创建一个可执行目标文件
  • 共享目标文件:这是一种特殊的可重定位目标文件,可以在运行时被动态加载进内存并链接

静态链接

  • 静态链接器以一组可重定位目标文件为输入,生成一个完全链接的可执行目标文件作为输出
  • 链接器主要完成以下两个任务
    • 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。
    • 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置

问题

  • 静态库更新时那么整个程序都要重新进行链接
  • 对于 printf 这种标准函数库,如果每个程序都要有代码,这会极大浪费资源

动态链接

共享库是为了解决静态库的这两个问题而设计的,在 Linux 系统中通常用 .so 后缀来表示,Windows 系统上它们被称为 DLL

  • 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中
  • 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享

硬链接和软连接

-1 个 inode 号对应多个文件名,则 为硬链接,(即硬链接就是同一个文件使用了不同的别名,使用ln创建)

-文件用户数据块中存放的内容是另一个文件的路径名指向,则该文件是软连接。软连接是一个普通文件 ,有独立inocde号

死锁

必要条件

  • 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
  • 保持和等待:已经得到了某个资源的进程可以再请求新的资源。
  • 不可剥夺:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
  • 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源

处理方法

预防死锁

  • 破坏互斥条件
  • 破坏请求和保持条件
  • 破坏环路等待:给资源统一编号,进程只能按照编号顺序请求资源(其实就是锁排序的思想)

死锁避免

在程序运行时避免发生死锁

  • 安装状态的检查
  • 银行家算法

死锁检测与恢复

不试图阻止死锁而是检测到死锁发生时采取措施恢复

  • 每种类型一个资源的死锁检测
  • 每种类型多个资源的死锁检测

死锁恢复:

  • 利用抢占恢复
  • 利用回滚恢复
  • 通过杀死进程恢复

鸵鸟策略

  • 解决死锁问题的代价很高
  • 当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值