操作系统常见八股文
操作系统常见八股文
线程和进程有什么区别?
- 进程:是资源分配的基本单位。每个进程都有自己独立的内存空间(如代码段、数据段、堆栈等),可以看作是一个独立运行的程序实例。进程之间相互独立。
- 线程:是CPU调度的基本单位。一个进程可以包含多个线程,线程共享进程的内存空间和资源(如文件句柄、数据段等),但每个线程有自己的独立栈和寄存器。
资源分配方式:
- 进程需要为其分配独立的内存空间和系统资源,因此创建和切换进程的开销较大。
- 线程共享进程的资源,因此创建和切换线程的开销较小,效率较高。
通信方式:
- 进程间通信需要使用复杂的机制(如管道、消息队列、共享内存、套接字等),因为各自拥有独立的内存空间。
- 同一进程内的线程共享内存,因此线程间通信更加方便,直接通过内存读写即可,但需要注意同步以避免数据冲突。
使用场景:
- 进程适用于需要较高隔离度和独立性的场景,如运行不同的服务或应用。
- 线程适用于需要高效执行、共享资源且任务关联性较高的场景,如多线程并发计算。
进程之间的通信方式有哪些?
进程间的通讯方式有管道、消息队列、共享内存、信号量、信号、套接字和文件
管道:管道是一种单向通信方式,通常用于父进程和子进程之间或同一主机上不同进程之间传递数据。
消息队列:消息队列允许一个进程向另一个进程发送消息。消息存储在队列中,按顺序存储,接收方可以按需读取。
共享内存:共享内存允许多个进程访问同一块内存区域,从而实现快速的数据交换。需要同步机制(如信号量)来避免竞态条件和数据一致性问题。
信号量 :信号量是一种同步机制,用于管理进程间对共享资源的访问,通常用于实现互斥锁和同步操作。
信号:信号是一种异步通信方式,通常用于通知目标进程发生了某个事件,例如中断或终止。
套接字:套接字允许在网络上的不同主机间或同一主机的不同进程间通信,是实现分布式系统的基础。通常用于跨主机的网络通信。
文件:进程可以通过读写共享文件来进行通信。通常适用于间接通信,例如通过临时文件或共享文件实现。
进程的调度算法你知道吗?
进程的调度算法主要有先来先服务、短作业优先、优先级调度、时间片轮转、最高响应比和多级反馈调度
- 先来先服务(FCFS, First-Come, First-Served):按照进程到达的顺序进行调度。简单易实现,适用于批处理系统。
- 缺点:可能导致“长任务”拖延其他任务的执行。
- 短作业优先(SJF, Shortest Job First):优先调度执行时间最短的进程。分为非抢占式和抢占式(SRTF, Shortest Remaining Time First)。
- 能减少平均等待时间,但需要预知任务执行时间,不适用于交互式系统。
- 优先级调度(Priority Scheduling):根据进程的优先级(权重)来调度,优先级高的进程先执行。适用于需要不同优先级服务的场景。
- 缺点:可能导致“低优先级进程”长时间得不到调度,即“饥饿现象”。
- 时间片轮转(RR, Round Robin):为每个进程分配固定的时间片,时间片结束后切换到下一个进程。适用于交互式系统,增强了系统的响应性。
- 时间片的选择可能影响系统性能。
- 最高响应比优先(HRRN, Highest Response Ratio Next):通过计算响应比决定下一个被调度的进程。防止短任务过多导致长任务的“饥饿”。平衡了任务的等待时间和执行时间。
- 多级反馈队列调度(MLFQ, Multilevel Feedback Queue):结合多个调度策略,通过将进程加入不同优先级的队列来实现调度。优先级较高的进程先被调度,长时间未完成的进程可能被降至低优先级队列。适合多任务、多类型的操作系统,具有灵活性。
为什么网络 I/O 会被阻塞?
等待数据到达或发送完成:如果数据未准备好,系统会让程序进入等待状态,直到数据到达或发送完成。
系统资源有限:当网络资源(如端口、连接等)被占满时,新的 I/O 请求需要等待资源释放。
默认的阻塞行为:大多数网络 API(如 recv、send、accept)在默认情况下是阻塞的,如果条件未满足,调用这些 API 时程序会等待操作完成。
如何解决阻塞问题?
可以采用非阻塞I/O方法,I/O多路复用以及异步I/O来解决,同时还可以为不同的请求分配单独的线程或使用轻量级的协程来处理阻塞操作
I/O模型有哪些?
常见的 I/O 模型有阻塞I/O、非阻塞I/O、I/O多路复用、信号驱动I/O、异步I/O
- **阻塞 I/O **:调用 I/O 操作时,进程会被阻塞,直到数据准备好或操作完成后才继续执行。
- 非阻塞 I/O :I/O 操作不会阻塞进程,如果数据未准备好,则立即返回错误或状态,进程可以继续执行其他操作。
- **I/O 多路复用 **:通过系统调用(如
select、poll、epoll等)实现,允许进程同时等待多个 I/O 操作。 - 信号驱动 I/O :当数据准备好时,内核通过信号通知进程进行 I/O 操作,进程在接收到信号后完成读取或写入。
- **异步 I/O ** :进程发起 I/O 请求后立即返回,内核在后台完成操作,并通过通知告知操作结果,进程无需等待即可继续执行其他任务。
Select、Poll、Epoll之间有什么区别?
Select:每次调用都需要重新构建和检查文件描述符集合,效率较低。支持的文件描述符数量有限(通常是1024),在大规模连接场景中效率低。
Poll:与 Select 类似,但用动态数组存储文件描述符,没有文件描述符数量限制。每次调用仍需遍历全部描述符,处理大量连接时效率不高。
Epoll:是 Select 和 Poll 的优化,效率更高。支持边缘触发(ET)和水平触发(LT)模式,适合高并发场景。只处理实际发生变化的描述符,无需遍历全部描述符,后续管理更加高效。
总结 :Select 和 Poll 都需要逐一检查文件描述符,效率低;而 Epoll 更智能高效,适用于大规模并发。
什么是用户态和内核态?
CPU有两种状态“内核态”(核心态、管态)和“用户态”(目态),用于区别应用程序与操作系统内核的操作权限。
CPU有一个寄存器叫程序状态字寄存器(PSW),其中有个二进制位,1表示“内核态”,0表示“用户态”
- 处于内核态时,说明此时运行的是内核程序,此时可以执行特权指令,可以直接访问硬件资源
- 处于用户态时,说明此时运行的是应用程序,此时只能执行非特权指令,不能直接访问硬件,应用程序需要通过系统调用与内核进行通信,由内核代为执行敏感操作。
内核态—>用户态:执行一条特权指令,修改PSW的标志位为“用户态”,这个动作意味着操作系统将主动让出CPU使用权
用户态—>内核态:由“中断”引发,硬件自动完成变态过程,处罚中断信号意味着操作系统将强行夺回CPU的使用权
- 中断信号:除非法使用特权指令外,其他凡是需要操作系统介入的地方都会触发中断信号
到底什么是 Reactor?
Reactor 是一种高效处理网络 I/O 的设计模式,适合开发需要高并发的网络服务。它的核心思想是通过 事件驱动机制 和 非阻塞 I/O,将 I/O 事件和具体的处理逻辑解耦,并通过事件分发器来管理事件和响应操作。
事件驱动:通过监听多个事件源(如连接、读写),一旦事件发生就调用对应的处理程序。
非阻塞 I/O:单线程或少量线程就能处理大量 I/O,避免线程切换的开销。
事件分发与处理:把不同的事件分配给相应的处理逻辑,做到快速响应和高效处理。
Reactor 就像一个调度员,负责监听各种“任务请求”,并快速把任务派给对应的“工人”(处理程序),从而实现高效、并发的任务处理。
(ps: reactor n.核反应堆)
为什么要有虚拟内存?
虚拟内存的核心作用:
提升系统效率:通过扩展地址空间和简化内存管理,让多个程序能高效运行,即使物理内存不足。
简化内存管理:操作系统自动分配和回收内存,无需开发者手动管理物理内存细节。
主要有三方面:
内存扩展能力:允许程序运行在比物理内存更大的地址空间上。使用交换(Swapping)技术,将不常用的内存页临时存储到磁盘,腾出空间给其他程序。
进程隔离:每个进程拥有独立的虚拟地址空间,防止进程之间的内存访问冲突。操作系统可通过页面表设置访问权限,防止非法访问。
简化内存管理:操作系统动态分配和回收内存,开发者无需关心物理内存布局。程序看到的内存是连续的虚拟地址,虚拟内存负责解耦物理内存与逻辑内存。
虚拟内存就像一个智能调度系统,利用硬盘扩展了内存容量,让系统在有限的物理资源下实现更多功能,同时为程序提供安全、稳定、易用的运行环境。
什么是分段、什么是分页?
分段:一种基于程序的逻辑结构划分内存的管理方式。例如,将程序划分为多个逻辑段(如代码段、数据段、堆栈段等)。
分页:一种将内存划分为固定大小的小块(称为页)和页框的管理方式。
分段的每个段的大小和长度可以根据程序的实际需求而不同,并不固定。各段之间通常是独立的,段号和段内偏移量决定了内存的访问方式。分段管理更贴近程序的逻辑结构,能提升程序的可读性和维护性。它让程序员可以更加专注于逻辑,而不用关心物理内存的实际分配。
分页的每一页和页框的大小是相同的,逻辑地址被划分为页号和页内偏移量。页通过页表映射到物理内存的页框中。分页解决了内存碎片问题,但逻辑地址结构和物理内存的组织方式不再一致。
什么是软中断、什么是硬中断?
硬中断是由硬件设备(如键盘、网卡、定时器等)触发的中断信号,用来通知 CPU 某些事件需要立即处理,硬中断是系统响应外部硬件事件的重要机制,能够确保对硬件的实时响应。例如,当键盘按下时,会触发硬中断,使操作系统能够捕获键盘输入。
软中断是由软件(如程序)触发的中断,通常通过执行特定指令(如 int 指令)或调用操作系统服务引发。软中断是程序与操作系统交互的一种手段,通过触发软中断,程序可以请求操作系统完成一些底层操作,如文件操作或内存分配。



