部分《操作系统》面试问题分享
可能不是很全,主要是我自己在准备秋招的时候找的一些参考答案
一、进程
程序段:能被进程调度到 CPU 执行的代码。
数据段:进程对应的程序加工处理的原始数据。
二、进程特征
并发性:多个进程可以同时存在于内存中,在一段时间内同时运行。
独立性:进程是一个能独立运行、独立接受调度的单位。
异步性:进程按不可预知的速度推进。
三、进程状态
就绪态:进程已处于准备运行的状态,获得了除处理机外的一切资源。
运行态:进程正在处理机上运行。
阻塞态:进程正在等待某一事件而暂停运行,如等待某资源可用或等待 IO 流完成。
结束态:进程正常结束或中断退出。
四、进程控制进程的创建
五、进程的终止
进程终止包括:正常结束,表示进程已经完成并准备退出;异常结束,表示进程在运行时发生异常,程序无法继续运行,例如非法指令,IO 故障等;外界干预,指进程因为外界请求而终止,例如操作系统干预等。
六、进程的阻塞与唤醒
正在执行的进程由于等待的事件未发生,由系统执行阻塞原语,由运行态变为阻塞态。
七、进程切换
进程切换是指处理机从一个进程的运行转到另一个进程上运行。
八、进程通信
(一)管道通信
Linux 里的 | 就是一个管道,功能是将前一个命令的输出作为后一个命令的输入。
管道通信中存储空间是内核缓冲区,只允许一边写、另一边读,只要缓冲区有数据,进程就能读出。写进程会先将缓冲区写满才让读进程读,当缓冲区还有数据时,写进程不会往缓冲区写数据。因此管道是半双工通信,效率低,不适合进程间频繁交换数据。
(二)消息队列
消息队列是保存在内核中的消息链表,消息的发送方和接收方要约定好消息体的数据类型,每个消息体都是固定大小的存储块,不像管道是无格式的字节流。如果进程从消息队列中读取了消息体,内核就会把这个消息体删除。消息队列的通信效率高于管道,进程发送消息时,把数据放在消息队列后就可以正常返回。
消息队列不适合较大数据的传输,因为内核中每个消息体都有最大长度限制。此外,消息队列通信存在数据拷贝开销,进程写数据到消息队列时,会发生从用户态拷贝数据到内核态的过程,读取数据时,会发生从内核态拷贝数据到用户态的过程。
(三)共享内存
共享内存解决了消息队列中用户态与内核态间的数据拷贝问题,将虚拟地址空间映射到相同的物理内存,当某个进程写数据时,另一个进程马上就能看到,不需要拷贝,提高通信效率。
九、线程是进程中的一个实体,是操作系统独立调度和分配的基本单位,由线程 ID、程序计数器、寄存器集合和堆栈组成。引入线程是为了减少程序并发执行的开销,进一步提高操作系统的并发性能。
线程和进程的区别
调度:进程是分配资源的基本单位,而线程是独立调度的基本单位。
资源:进程拥有系统资源,而线程只有一点运行必需的资源。如果线程也是分配资源的单位,切换就需要较大开销,引入没有意义。
开销:进程切换涉及当前 CPU 环境的保存和设置,但线程切换只需要保存和设置少量的寄存器容量。
地址空间:进程的地址空间互相独立,同一进程的线程共享进程资源,进程内的线程对其他进程不可见。
通信:进程通信需要同步和互斥手段的辅助,保证数据一致性。线程可以直接读写进程数据段(全局变量)来进行通信。
十、线程实现
(一)内核级线程 1:1 实现
内核通过操纵调度器对线程进行调度,并将线程的任务映射到处理器上。程序一般不会直接使用内核线程,而是使用内核线程的一种高级接口,轻量级进程,即通常意义上的线程。
优点:当一个线程被阻塞时,允许其他线程继续执行。
缺点:代价相对较高,需要在用户态和内核态来回切换。
(二)用户级线程 1:N 实现
从广义上讲,一个线程只要不是内核线程,就可以认为是用户线程。狭义上的用户线程指的完全建立在用户空间的线程库上,系统内核不能感知到用户线程的存在及其是如何实现的。
优点:由于线程管理在用户空间进行,不需要切换到内核态,开销小,支持大规模并发。
缺点:一个线程在使用内核服务时被阻塞,整个进程都会被阻塞。
(三)混合方式 N:M 实现
混合模式下既存在用户线程,也存在轻量级进程。用户线程完全建立在用户空间中,因此开销依然很小,可以支持大规模并发。轻量级进程作为用户线程和内核线程之间的桥梁,使用内核提供的线程调度功能及处理器映射,降低整个进程阻塞的风险。
十一、死锁就是指多个进程因为互相竞争资源而造成的一种互相等待的僵局,若无外力作用,这些进程都无法继续向前推进。
(一)死锁的原因
(1)不可剥夺资源数量的不足,如打印机,对可剥夺资源的竞争不会造成死锁。
(2)进程请求和释放资源的顺序不当,例如进程 P1 和 P2 分别占用资源 R1 和 R2,而此时 P1 和 P2 又分别申请资源 R2 和 R1。
(3)信号量的使用不当,进程间彼此互相等待对方发来的消息,也会使进程无法推进。
(二)必要条件
(1)互斥条件:进程对资源的占有具有排它性,如果进程请求的资源已被占用,请求就会被阻塞。
(2)不可剥夺条件:进程获得的资源没有使用完成前,不能被其它进程强行获取,只能由占有它的进程主动释放。
(3)请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求被阻塞,但进程也不会释放自己已经占有的资源。
(4)循环等待条件:存在一个进程资源的循环等待链,链中每个进程已经占有的资源同时是其他进程请求的资源。
十二、死锁处理
(二)避免
十三、死锁检测
系统死锁可用资源分配图描述,圆圈表示进程,框表示资源。从进程到资源的有向边是请求边,从资源到进程的边是分配边。
简化资源分配图可以检测系统状态是否为死锁状态。在资源分配图中,找出既不阻塞也不孤立的进程,消去它的所有请求边和分配边,使之成为孤立的点。如果系统状态不可被完全简化,那么代表死锁。