操作系统面经

2023年 9月 21日 60.5k 0

● 内核态和用户态是什么

○ 用户态:用户态运行的程序只能受限地访问内存,只能直接读取用户程序的数据,并且不允许访问外围设备,用户态下的 CPU 不允许独占,也就是说 CPU 能够被其他程序获取

○ 内核态:内核态运行的程序可以访问计算机的任何数据和资源,不受限制,包括外围设备,比如网卡、硬盘等。处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况

○ 所有的用户进程都是运行在用户态的,用户程序的访问能力有限,一些比较重要的比如从硬盘读取数据,从键盘获取数据的操作则是内核态才能做的事情,而这些数据却又对用户程序来说非常重要。所以就涉及到两种模式下的转换,即用户态 -> 内核态 -> 用户态,而唯一能够做这些操作的只有 系统调用,而能够执行系统调用的就只有 操作系统

● 进程、线程、协程的区别和联系

○ 进程与线程

■ 调度:进程是资源分配的基本单位,线程是CPU调度的基本单位;

■ 并发性:一个进程内多个线程可以并发(最好和CPU核数相等);多个进程可以并发。

■ 拥有资源:线程不拥有系统资源,但一个进程的多个线程可以共享隶属进程的资源;进程是拥有资源的独立单位。

■ 系统开销:进程和线程切换时,需要切换进程和线程的上下文,进程的上下文切换时间开销远远大于线程上下文切换时间,耗费资源较大,效率要低一些

○ 协程是微线程,在子程序内部执行,可在子程序内部中断,转而执行别的子程序,在适当的时候再返回来接着执行

○ 线程与协程:

■ 协程执行效率极高,协程直接操作栈基本没有内核切换的开销,所以上下文的切换非常快,切换开销比线程更小。

■ 协程不需要多线程的锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率比线程高。

■ 一个线程可以有多个协程

● 进程的状态

○ 

image.png
○ 创建状态(new):进程正在被创建,尚未到就绪状态。

○ 就绪状态(ready):进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。

○ 运行状态(running):进程正在处理器上运行(单核 CPU 下任意时刻只有一个进程处于运行状态)。

○ 阻塞状态(waiting):又称为等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO 操作完成。即使处理器空闲,该进程也不能运行。

○ 结束状态(terminated):进程正在从系统中消失。可能是进程正常结束或其他原因中断退出运行

■ 其中只有就绪状态和运行状态能互相转化,当进程为就绪态时,等待 CPU 分配时间片,得到时间片后就进入 运行状态 运行状态在使用完 CPU 时间片后,又重回就绪态。 

■ 阻塞状态是进程在运行状态时,需要等待某个资源比如打印机资源,而进入一个挂起的状态,等资源拿到后会回到就绪状态,等待 CPU 时间片。

● PCB是什么

○ 进程控制块PCB,是进程存在的唯一标志,是进程实体的一部分

○ 包含内容:

■ 进程标识符PID,进程名称

■ 进程调度信息,比如阻塞原因,状态,优先级等等

■ 进程控制和资源占用,同步通信机制,链接指针(指向队列中下一个进程的 PCB 地址)

● 进程间的通信方式

○ 管道/匿名管道(Pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有血缘关系的进程间使用。进程的血缘关系通常指父子进程关系。

○ 有名管道(Named Pipes) : 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循 先进先出(First In First Out) 。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信

○ 信号量(Semaphores) :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步,这种通信方式主要用于解决与同步相关的问题并避免竞争条件。

○ 信号(Signal):信号是一种比较复杂的通信方式,用于通知接收进程某一事件已经发生。

○ 共享内存(Shared memory) :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等,可以说这是最有用的进程间通信方式。

○ 消息队列(Message queue):消息队列是由消息组成的链表,a 进程要给 b 进程发消息,只需要把消息挂在消息队列(可以是中介邮局,也可以是进程自己的信箱)里就行了,b 进程需要的时候再去取消息队列里的消息。 消息队列可以独立于读写进程存在,就算进程终止时,消息队列的内容也不会被删除。 读进程可以根据消息类型有选择的接收消息,而不像 FIFO 那样只能默认接收。

○ 套接字(Socket):Socket 套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。

● 线程间的通信方式

image.png
○ 信号:类似进程间的信号处理

○ 锁机制:互斥锁、读写锁和自旋锁

○ 条件变量:使用通知的方式解锁,与互斥锁配合使用

○ 信号量:包括无名线程信号量和命名线程信号量

● 同步和异步,阻塞和非阻塞的区别

○ 阻塞是指当一个进程执行某个操作时,如果该操作没有完成,进程会被挂起,等待操作完成后再继续执行。在阻塞状态下,进程无法进行其他的操作,直到阻塞的操作完成或者被取消。

○ 非阻塞是指当一个进程执行某个操作时,如果该操作没有完成,进程不会被挂起,而是立即返回一个错误码或者一个特殊的值,继续执行其他的操作。在非阻塞状态下,进程可以进行其他的操作,无需等待阻塞的操作完成

○ 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,知道收到返回信息才继续执行下去;

○ 异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回式系统会通知进程进行处理,这样可以提高执行的效率

● 进程调度策略

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

○ 短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。

○ 时间片轮转(RR)调度算法 : 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间段,称作它 的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU 当即进行切换。。

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

○ 多级反馈队列调度算法 :前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成,因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法

● 守护进程,僵尸进程,和孤儿进程 分别是什么 

○ 守护进程:指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,周期性地执行某种任务。Linux的大多数服务器就是用守护进程的方式实现的,如web服务器进程http等

○ 僵尸进程:子进程已经终止,但是其父进程仍在运行,且父进程没有调用 wait()或 waitpid()等系统调用来获取子进程的状态信息,释放子进程占用的资源,导致子进程的 PCB 依然存在于系统中,但无法被进一步使用。这种情况下,子进程被称为“僵尸进程”。避免僵尸进程的产生,父进程需要及时调用 wait()或 waitpid()系统调用来回收子进程。

○ 孤儿进程:一个进程的父进程已经终止或者不存在,但是该进程仍在运行。这种情况下,该进程就是孤儿进程。孤儿进程通常是由于父进程意外终止或未及时调用 wait()或 waitpid()等系统调用来回收子进程导致的。为了避免孤儿进程占用系统资源,操作系统会将孤儿进程的父进程设置为 init 进程(进程号为 1),由 init 进程来回收孤儿进程的资源

● 什么是死锁,产生的条件是什么

○ 死锁:多个进程/线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于进程/线程被无限期地阻塞,因此程序不可能正常终止

○ 产生条件(缺一不可)

■ 互斥 条件:进程对所需求的资源具有排他性,若有其他进程请求该资源,请求进程只能等待。

■ 不剥夺 条件:进程在所获得的资源未释放前,不能被其他进程强行夺走,只能自己释放。

■ 请求和保持 条件:进程当前所拥有的资源在进程请求其他新资源时,由该进程继续占有。

■ 循环等待 条件:存在一种进程资源循环等待链,链中每个进程已获得的资源同时被链中下一个进程所请求

● 内存管理的机制

●  分块管理,是连续管理的一种,把内存分为几个大小相等且固定的块,每个进程占用其中一个,如果进程很小的话,会浪费大量的空间。已经淘汰。 

●  分页管理,把内存分为若干个很小的页面,相对比分块的划分力度更大一些。提高内存利用率。减少碎片,页式管理通过页表对应逻辑地址和物理地址。 

●  分段管理,把内存分为几个大小不定的有实际意义的段,比如 main 函数段,局部变量段,通过管理段表来把逻辑地址转为物理地址。  

● 段页式管理,结合了段式管理和页面管理的优点,把主存先分为若干个段,每个段又分为若干个页,也就是说段页式管理的段与段以及段的内部都是离散的。

● 分页和分段的区别和联系

○ 联系

■ 内存分段和分页都是用于管理虚拟地址与物理地址之间的关系

■ 都是离散分配的,单每个页和每个段的内存是连续的

○ 区别

■ 分页机制以页面为单位进行内存管理,而分段机制以段为单位进行内存管理。页的大小是固定的,由操作系统决定,通常为 2 的幂次方。而段的大小不固定,取决于我们当前运行的程

■ 分页机制采用了页表来完成虚拟地址到物理地址的映射,页表通过一级页表和二级页表来实现多级映射;而分段机制则采用了段表来完成虚拟地址到物理地址的映射,每个段表项中记录了该段的起始地址和长度信息

● 虚拟内存

○ 传统的内存管理必须把作业一次性的 load 到内存中,并且一直驻留到其作业运行结束,当作业很大时,是没有办法一次性装入内存的

○ 在一段时间内,只需要访问小部分数据就可以保证程序的正常运行。所以基于局部性原理,在程序加载的时候,把很快就会用到的部分放入内存中,暂时用不到的部分留在磁盘上。在程序执行的过程中,当信息不在内存时,再从外存把信息加载到内存里。当内存不够的时候,根据一些策略把用不到的内存换出到外存中,从而腾出空间给要调入内存的信息。而在 os 的管理下,让应用程序认为自己拥有一连续可用的内存,产生独享主存的错觉,这就是虚拟内存

○ 虚拟内存从逻辑上实现了对内存容量的扩充,让用户感觉到的内存容量比实际内存容量大得多,因此可以让内存空间更大的程序运行,或者让更多的用户程序并发运行,既满足了用户的需要又改善了系统的性能

● 页面置换(淘汰机制)算法

● OPT 页面置换法,最佳页面置换:不可实现,不可预测哪个是不用的。

●  FIFO 先到先出算法,把在内存中停留时间最长的页面置换出去 LRU 最近最久未使用页面置换算法:

● LRU 算法赋予每一个页面一个访问字段,来记录一个页面最近一次访问到现在所经历的时间 T,需要淘汰一个页面时,把最久没有使用的页面淘汰掉就可以了。

●  LFU 最少使用算法:把使用最少的页面淘汰掉

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论