操作的系统的面试问题很多,时间有限,我只关注这三方面的问题。进程和线程、死锁、内存管理。
一、进程和线程
1. 进程和线程的区别【车间和工人的区别】
a.进程是资源分配的基本单位,线程是cpu调度或者说是程序执行的最小单位。
b.进程有独立的地址空间,而运行一个进程中的线程,它们之间共享大部分数据,使用相同的地址空间,因此启动一个线程比进程操作要快,花费也要小得多。
c.线程之间的通信比较方便。统一进程下的线程共享数据(比如全局变量,静态变量),通过这些数据来通信不仅快捷而且方便,当然如何处理好这些访问的同步与互斥正是编写多线程程序的难点。而进程之间的通信只能通过进程通信的方式进行。
e.线程的执行与进程是有区别的。每个独立的线程有有自己的一个程序入口,顺序执行序列和程序的出口,但是线程不能独立执行,必须依附与程序之中,由应用程序提供多个线程的并发控制。
2. 进程和线程的同步机制
进程同步机制:
原子操作、信号量机制、自旋锁管程、会合、分布式系统
线程同步机制:
– 互斥量
采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。
– 信号量
它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
– 事件(信号)
通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。
3. 进程的状态
就绪状态
进程已获得除处理机以外的所需资源,等待分配处理机资源运行状态
占用处理机资源运行,处于此状态的进程数小于等于CPU数阻塞状态
进程等待某种条件,在条件满足之前无法执行4. 进程的调度策略
FCFS(先来先服务),优先级,时间片轮转,多级反馈
5. 进程之间的通信方式
主要分为:管道、系统IPC(包括消息队列、信号量、共享存储)、SOCKET管道是一种半双工的通信方式,数据只能单项流动,并且只能在具有亲缘关系的进程间流动,进程的亲缘关系通常是父子进程命名管道也是半双工的通信方式,它允许无亲缘关系的进程间进行通信
信号量是一个计数器,用来控制多个进程对资源的访问,它通常作为一种锁机制。
消息队列是消息的链表,存放在内核中并由消息队列标识符标识。
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
共享内存就是映射一段能被其它进程访问的内存,这段共享内存由一个进程创建,但是多个进程可以访问。
二、死锁
1. 死锁及其产生的条件
在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。
产生死锁的原因:(1)竞争系统资源 (2)进程的推进顺序不当
死锁产生的四个条件(有一个条件不成立,则不会产生死锁)
互斥条件:一个资源一次只能被一个进程使用
请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放
不剥夺条件:进程获得的资源,在未完全使用完之前,不能强行剥夺
循环等待条件:若干进程之间形成一种头尾相接的环形等待资源关系
2. 解决死锁的基本方法
- 预防死锁
- 避免死锁
- 检测死锁
- 解除死锁:
三、内存管理
1. Windows内存管理的方式
块式、虚拟内存分页式、虚拟内存分段式、段页式
2. 内存连续分配方式采用的几种算法
首次适应算法、循环首次适应算法、最佳适应算法、最差适应算法
3. 分段分页方式的比较各自优缺点。
分段和分页其实都是一种对地址的划分或者映射的方式。
1)页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要(也是对用户透明的)。段是信息的逻辑单位,它含有一组其意义相对完整的信息(比如数据段、代码段和堆栈段等)。分段的目的是为了能更好的满足用户的需要(用户也是可以使用的)。
2)页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。
3)分页的作业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符(线性地址的16进制表示),即可表示一地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名(比如数据段、代码段和堆栈段等),又需给出段内地址。
4)页和段都有存储保护机制。但存取权限不同:段有读、写和执行三种权限;而页只有读和写两种权限
4. 几种页面置换算法,会算所需换页数。(LRU用程序如何实现?)
1)最佳置换算法(OPT)(OPTimalreplacement理想置换算法)
这是一种理想情况下的页面置换算法,但实际上是不可能实现的。该算法的基本思想是:发生缺页时,有些页面在内存中,其中有一页将很快被访问(也包含紧接着的下一条指令的那页),而其他页面则可能要到10、100或者1000条指令后才会被访问,每个页面都可以用在该页面首次被访问前所要执行的指令数进行标记。最佳页面置换算法只是简单地规定:标记最大的页应该被置换,选择下次访问距当前时间最长的那些页。这个算法唯一的一个问题就是它无法实现。当缺页发生时,操作系统无法知道各个页面下一次是在什么时候被访问。虽然这个算法不可能实现,但是最佳页面置换算法可以用于对可实现算法的性能进行衡量比较。
2)先进先出置换算法(FIFO)
最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。建立一个FIFO队列,收容所有在内存中的页。被置换页面总是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。
这种算法只是在按线性顺序访问地址空间时才是理想的,否则效率不高。因为那些常被访问的页,往往在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。
FIFO的另一个缺点是,它有一种异常现象,即在增加存储块的情况下,反而使缺页中断率增加了。当然,导致这种异常现象的页面走向实际上是很少见的。
3)最近最久未使用(LRU)算法
FIFO算法和OPT算法之间的主要差别是,FIFO算法利用页面进入内存后的时间长短作为置换依据,而OPT算法的依据是将来使用页面的时间。如果以最近的过去作为不久将来的近似,那么就可以把过去最长一段时间里不曾被使用的页面置换掉。它的实质是,当需要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。这种算法就称为最久未使用算法(Least Recently Used,LRU)。LRU算法是与每个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。虽然LRU策略的性能接近OPT策略,但是问题在于这种策略比较难实现。
5. 虚拟内存的定义及实现方式。
虚拟内存是指为了扩充主存空间而在外存上开辟的一块存储空间.虚拟内存用来保存实际内存中暂时不用的程序或数据,使实际内存有更多的空闲空间来存放将要执行的程序或访问的数据,当需要执行的程序或访问的数据不在主存时,就从虚拟内存将其调入到主存,以便处理器执行或访问,这样就扩大了内存空间,操作系统对实际内存和虚拟内存统一编址和统一管理,这就是虚拟内存技术.
大多数的多任务操作系统都采用分页存储方式,使用虚拟内存技术。UNIX操作系统采用页面存储方式,Windows NT采用请求分页的虚拟存储方式,linux系统采用按需调页的模式。在AIX系统中,也使用分页的存储方式管理存储器,并将虚拟内存称为页面空间(Paging Space),所有对实际物理内存和虚拟内存的访问都是由虚拟内存管理器(VMM)完成的。