文章目录
什么是死锁?
- 由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行
面试官:讲讲什么是死锁?
小白菜:你录取我,我就给你讲
面试官:你给我讲,我就录取你
小白菜:你录取我,我就给你讲
面试官:你给我讲,我就录取你
…
死锁产生的原因:资源竞争、进程推进顺序不当。
如何避免死锁
死锁避免
- 在系统运行过程中,对进程提出的每一个(系统能够满足的)资源申请进行动态检查(安全性检查);
- 根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配。
死锁的预防
- 具体的做法是破坏产生死锁的四个必要条件之一。加粗样式
- 原理为:设计不同的资源分配算法,来保证不发生死锁。
死锁的解除:
- 破坏产生死锁的四个必要条件之一即可。
- 强制性地从系统中撤销一个或多个死锁的进程以断开循环等待链。
- 强制性抢占死锁进程正在争取的资源以解除死锁。
死锁的必要条件
-
互斥条件:所谓互斥就是进程在某一时间内独占资源。
-
请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
-
不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
-
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
进程和线程的区别?
从四个方面分析
- 调度:进程是资源管理的基本单元,线程是程序执行的基本单元。
- 切换:线程上下文切换比进程上下文切换快得多。
- 拥有资源:进程是拥有资源的一个独立单独。而线程没有系统资源,但可以访问隶属于进程的资源。
- 系统开销:创建或撤消进程时,系统都要为之分配或回收系统资源,如内存空间、I/O设备等,OS的成本明显高于创建或撤消线程时的成本,而进程切换的成本也比线程切换的成本高得多。
线程共享进程中哪些资源,独享哪些资源
共享资源
- 代码区、数据区、堆区
- 进程地址空间中的代码区,更准确的是编译后的可执行机器指令。
- 数据区进程地址空间中的数据区,这里存放的就是所谓的全局变量。
- 堆区,new出来的数据就存放在这个区域,很显然,只要知道变量的地址,也就是指针,任何一个线程都可以访问指针指向的数据,
独享资源
-
所属线程的栈区、程序计数器、栈指针以及函数运行使用的寄存器是线程私有的
-
程序计数器的寄存器中保存了接下来要执行哪一条指令(CPU执行指令的信息)以及部分局部变量之类
-
程序计数器中又保存了线程的中断信息等(由于操作系统随时可以暂停线程的运行,因此我们保存以及恢复程序计数器中的值就能知道线程是从哪里暂停的以及该从哪里继续运行了)
-
由于线程运行的本质就是函数运行,函数运行时信息是保存在栈帧中的,因此每个线程都有自己独立的、私有的栈区。一个线程不可能访问到另一个线程的这类寄存器信息
线程、进程的通信方式
线程
- 互斥量 Synchronized/Lock:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。
- 信号量 Semphare:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
- 事件(信号),Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作
进程六种
-
管道及有名管道
- 匿名管道:半双工通信,数据只能单向流动并且只能在具有亲缘关系的进程之间使用。进程的亲缘关系通常是指父子进程关系。
- 命名管道:也是半双工通信,但可以支持本机进程之间的任意两个通信。
-
信号
- 用于通知接收进程某个事件已经发生,信号可以任何时候发个某个进程,而无需知道该进程的状态
-
信号量
- 是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
-
消息队列
- 是由消息的链表,存放在内核中并由消息队列标识符标识,有足够的权限的进程可以向队列中添加信息。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点
-
共享内存
- 就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问
-
套接字
- (socket)也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
信号量与信号的区别?
信号就是一种异步通信,通知进程某种事件的发生;信号量是进程/线程同步与互斥的一种机制,保证进程/线程间之间的有序执行或对公共资源的有序访问。
-
信号:(signal)是一种处理异步事件的方式。信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。
-
信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
计算机插上电源操作系统做了什么?
-
加电––––打开电源开关,给主板和内部风扇供电。
-
启动引导程序––––CPU 开始执行存储在 ROM BIOS 中的指令。
-
开机自检––––计算机对系统的主要部件进行诊断测试。
-
加载操作系统––––计算机将操作系统文件从磁盘读到内存中。
-
检查配置文件,定制操作系统的运行环境––––读取配置文件,根据用户的设置对操作
系统进行定制。 -
准备读取命令和数据––––计算机等待用户输入命令和数据。
虚拟内存是什么,虚拟内存的原理是什么?
虚拟内存允许执行任务的进程不必完全在内存中。很多时候我们使用点开了很多占内存的软件,这些软件占用的内存可能已经远远超出了我们电脑本身具有的物理内存。 正是因为 虚拟内存 的存在,通过 虚拟内存 可以让程序可以拥有超过系统物理内存大小的可用内存空间(把内存扩展到硬盘空间)
虚拟内存是计算机系统内存管理的一种技术。
虚拟内存有以下两个优点:
- 虚拟内存地址空间是连续的,没有碎片。
- 虚拟内存的最大空间就是 cup 的最大寻址空间,不受内存大小的限制,能提供比内存更大的地址空间。
当每个进程创建的时候,内核会为每个进程分配虚拟内存,这个时候数据和代码还在磁盘上, 当运行到对应的程序时,进程去寻找页表,如果发现页表中地址没有存放在物理内存上,而是 在磁盘上,于是发生缺页异常,于是将磁盘上的数据拷贝到物理内存中并更新页表,下次再访 问该虚拟地址时就能命中了
进程、线程的上下文切换
-
进程上下文切换
一个进程切换到另一个进程运行,称为进程的上下文切换。进程是由内核管理和调度的,所以进程的切换只能发生在内核态。
-
线程上下文切换
多线程编程中一般线程的个数都大于CPU核心的个数。
但一个线程时间片用完后,会重新处于就绪状态并让给其他线程使用,这个过程属于一次上下文切换。
概括:当前任务在执行完CPU时间片切换到另一个任务前会保存自己的状态,以便下一次再切换回这个任务时,可以再加载这个任务的状态。
如何减少线程的上下文切换?
多线程竞争时,会引起上下文切换。
- 无锁并发编程:用一些办法来避免使用锁,如将数据的ID按照Hash取模分段,不同线程处理不同段数据。
- CAS算法:Java的Atomic包使用CAS算法来更新数据,而不需加锁。
- 使用最少线程:避免创建不需要的线程。
- 协程:在单线程里实现多任务的调度,维持多任务间的切换。
操作系统进程的调度策略?
为了确定首先执行哪个进程以及最后执行哪个进程以实现最大 CPU 利用率,计算机科学家已经定义了一些算法,它们是:
-
先到先服务(FCFS)调度算法 : 从就绪队列中选择一个
最先进入该队列的进程
为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。 -
短作业优先(SJF)的调度算法: 从就绪队列中选出一个
运行时间最短的进程
为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用 CPU 时再重新调度。- 缺点:仅照顾了短进程而忽略了长进程。
-
时间片轮转调度算法 : 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称 RR(Round robin)调度。每个进程被分配一个时间片,时间片用尽则退出对CPU资源的使用。
-
优先级调度 : 为每个进程分配优先级,首先执行具有最高优先级的进程**,依此类推。**具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
- 存在的主要问题是:低优先级进程无穷等待CPU。导致线程饥饿
-
多级队列调度算法:将就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。其中,一个进程根据自身属性被永久、固定地分配到一个队列中。
-
多级反馈队列调度算法 :目前
被公认的一种较好的进程调度算法
,UNIX 操作系统采取的便是这种调度算法。与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多CPU时间,那么它会被转移到优先级更低的队列;在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。
操作系统内存管理方式
内存管理方式:块式管理、页式管理、段式管理、段页式管理。
分段管理
- 在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。
分页管理
- 在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的页框,程序加载时,可以将任意一页放入内存中任意一个页框,这些页框不必连续,从而实现了离散分离。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。
段页式管理
- 段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。
讲一讲操作系统的I/O模型?什么是I/O多路复用?
I/O请求有两个阶段:
- 等待资源阶段:I/O请求一般需要请求特殊的资源(如磁盘、RAM、文件),当资源被上一个使用者使用没有被释放时,IO请求就会被阻塞,直到能够使用这个资源。
- 使用资源阶段:真正进行数据接收和发送。
在等待数据阶段,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 多路复用可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写。
正因为阻塞I/O只能阻塞一个I/O操作,而I/O复用模型能够阻塞多个I/O操作,所以才叫做多路复用