经典面试题-操作系统
进程,线程,协程有什么关系和区别
进程是程序资源分配管理的最小单位,线程是资源调度的最小单位,其中,一个进程可以包含多个线程,而这些线程又共享该进程的资源,在Java20之后,又推出了协程的概念,协程是用户态的轻量级线程,不受操作系统的调度,由程序员或库进行控制,并且协程的创建和销毁都由用户空间完成,开销非常小;
他们三者的区别主要分为以下几点:
开销大小: 进程 > 线程 > 协程
资源分配: 进程是资源分配的单位,线程和协程是资源调度的单位
地址空间: 进程有独立的地址空间,线程共享所在进程的地址空间,协程共享所在线程的地址空间
调度方式: 进程和线程由操作系统调度,协程由用户或者库调度
什么是用户态和内核态
在操作系统中,处理器有两种主要的运行模式,即内核态(Kernel Mode)和用户态(User Mode)。
当进程执行系统调用、处理硬件中断或者存在特权指令执行需求时,其运行在内核态,此时处理器具有较高的权限,可以直接访问计算机硬件资源。而当进程执行普通的应用程序代码时,它运行在用户态,对系统资源的访问受到限制,不能直接进行如硬件操作、内存管理等敏感操作,以保证系统的稳定性和安全性。
进程间的通信方式有哪些
○ 管道: 能实现进程间单向的数据传输,但只能用于父子进程和兄弟进程之间
○ 命名管道: 同管道的作用,但是他可以实现任意进程间的通信
☆ 共享内存: 通过共享内存块的方式进行进程间的通信,多个进程可访问同一个共享内存区域,并在该区域中进行数据读写
☆ 信号: 信号是一种异步通信方式,进程可通过发送信号来通知其他进程或处理待定事件
△ 套接字(Socket): 套接字是一种通过网络进行进程间通信的方式
消息队列: 消息队列是一种通过消息传递的方式进行进程间的通信
进程间的调度方式有哪些?举出常用的调度机制
抢占式: (当一个进程正在处理机上执行时,如果来了一个更重要的进程,则立即暂停当前进程,将处理机分配给更重要的进程)
最短剩余时间优先: 短作业优先的抢占式版本,当一个新作业到达,其整个运行时间和当前进程剩余时间作比较,哪个能最快运行完毕,就运行哪个进程
时间片轮转: 给每个进程都设置时间片,时间片用完就会切换进程(虽然公平,但是频繁切换,有开销)
抢占式优先级: 动态设置进程的优先级,
多级反馈: 综合 时间片轮转算法 和 最高优先级算法
非抢占式:(只允许程序主动放弃虚拟机,就算运行中有更紧迫的进程到来,当前进程依然执行,直到该进程终止或进入阻塞状态)
先来先服务: 从就绪队列挑选最先进入的进程执行(实现简单,但不适合短作业或I/O密集型进程)
短作业优先: 按照剩余执行时间最短的进程执行(虽然减少了平均等待时间,但需要优先知道进程执行时间,且容易长作业饥饿,实现困难)
高响应比优先: 响应比为等待时间/服务时间,相应比高的优先执行(避免饥饿)
非抢占式优先级: 创建进程时就设定了优先级
浅谈死锁
什么是死锁
死锁是指在多个进程中,每个进程都占有某个资源,同时又在等待其他进程释放他们所需要的资源,导致所有进程都无法执行的一种状态
产生的原因
- 竞争资源
- 不恰当的资源分配策略
- 循环依赖
解决策略
预防死锁: 合理分配资源,避免循环依赖
避免死锁: 通过安全序列
检测死锁: 使用资源分配图检测
解除死锁: 通过中断进程或回收进程的占用资源等
常见的进程种类
饥饿进程:
在操作系统中,饥饿进程(Starvation)并不特指一种进程状态,而是指一种现象。当一个或多个进程因为系统调度策略或其他进程的行为导致长时间得不到CPU资源,无法继续执行的现象称为“饥饿”。即使这些进程是可运行状态(Ready),但由于优先级调度、资源竞争等原因,可能会长时间得不到调度,从而无法向前推进。
僵尸进程:
僵尸进程(Zombie Process)是指一个已经终止运行的进程,但在操作系统中仍然保留了一条记录,即进程控制块(PCB)。正常情况下,当子进程结束后,应当向其父进程报告退出状态,父进程通过调用wait()或waitpid()等系统调用来接收这个状态并释放子进程占用的系统资源。如果父进程未能及时这样做,子进程的状态就会停留在“已终止”但仍存在于进程表中,占用最少的系统资源(如进程描述符),这样的进程就被称为僵尸进程。
孤儿进程:
孤儿进程(Orphan Process)是指父进程在子进程之前结束,导致子进程失去了父进程。在这种情况下,操作系统会自动把该子进程的父进程设置为init进程(在Unix/Linux系统中,PID为1的进程)。init进程会定期检查并回收孤儿进程的资源,因此孤儿进程不会像僵尸进程那样永久占用系统资源。
守护进程:
守护进程(Daemon Process)是一种在后台运行的特殊进程,不与任何终端关联,也不会直接与用户交互。它们通常会在系统启动时启动,并在整个系统运行期间持续运行,执行各种后台服务,例如网络服务、定时任务、日志管理等。守护进程脱离了控制终端,这样即使终端关闭或用户注销,它们依然能够继续运行,为系统或用户提供必要的支持和服务。守护进程的父进程往往是init进程或systemd(在现代Linux发行版中常见的情况)。