操作系统笔试面试基本内容
一、笔试内容
1、内核对象
定义:内核对象的数据结构只能被内核访问,因此应用程序无法在内存中找到这些数据结构并直接改变它们的内容。CreateFileMapping函数可使系统能够创建一个文件映射对象。每个内核对象只是内核分配的一个内存块,并且只能由该内核访问。该内存块是一种数据结构,它的成员负责维护该对象的各种信息。有些数据成员(如安全性描述符、使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型。
分类:存取符号对象、事件对象、文件对象、文件映射对象、I / O完成端口对象、作业对象、信箱对象、互斥对象、管道对象、进程对象、信标对象、线程对象和等待计时器对象等。
判别:若要确定一个对象是否属于内核对象,最容易的方法是观察创建该对象所用的函数。
2、临界区和互斥体的区别:
临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。
临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。
临界区和互斥体在Windows平台都下可用;Linux下只有互斥体可用。
3、一个进程中所有线程共享的内容:地址空间,全局变量,打开文件,子进程,即将发生的报警,信号与信号处理程序和账户信息
每个线程自己的独有的内容:程序计数器,寄存器,堆栈,状态
创建进程:fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。
具体的fork分析过程请参考以下链接:http://www.cnblogs.com/bastard/archive/2012/08/31/2664896.html 。主要介绍循环中的fork函数的具体调用情况。与此相关的一个是printf()函数。它的缓冲机制:系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上。但是,只要看到有\n 则会立即刷新stdout,因此就马上能够打印了。运行了printf("fork!")后,“fork!”仅仅被放到了缓冲里;而运行printf("fork! \n")后,“fork!”被立即打印到了屏幕上,之后fork到的子进程里的stdout缓冲里不会有fork! 内容。
4、虚拟内存的基本思想是:
每个程序拥有自己的地址空间,这个空间被分割成多个块,每个块称作一页或者页面。每一页有连续的地址范围,这些页被映射到物理内存,但并不是所有的页都必须在内存中才能运行程序。如果MMU(内存管理单元)注意到该页面没有被映射,于是使CPU陷入到操作系统,这个陷阱称为“缺页中断”。当发生缺页中断时,操作系统必须在内存中选择一个页面将其换出内存,以便为即将调入的页面腾出空间。对于先进先出(FIFO)页面置换算法而言,只需判断载入的页是否已存在即可,存在则为命中;否则将最先存储的页面淘汰,并将载入的页面存储进去(FIFO)。对于LRU页面置换算法而言,唯一的区别在于当载入的页已经存在,就将该页调到最上层。
假设物理内存可以存储3页,即从第四项开始检查选择页前面的三项中是否包含当前页,如果没有则缺页,则根据FIFO算法置换页面;否则则为页面命中。若进程在内存中占3页,开始时内存为空,当执行以下访问页号序列后1,3,4,2,1,3,5,1,2,5,4,2,会产生3+6=9次缺页。
5、I/O设备大致可以分为两类:块设备和字符设备。
块设备把信息存储在固定大小的块中,每个块有自己的地址。块设备的基本特征是每个块都能独立于其他块而读写。硬盘,CD-ROM和USB盘是最常见的块设备。字符设备以字符为单位发送或接收一个字符流,是不可寻址的,也没有任何寻道操作。打印机、网络接口、鼠标都是字符设备。
I/O设备中的电子部件称作设备控制器或适配器,控制器的任务是把串行的位流转换成字节块,并进行必要的错误校正工作。每个控制器有几个寄存器用来与CPU进行通信。通过写入这些寄存器,操作系统可以命令设备发送数据、接收数据、开启或关闭,或者执行某些其他操作。通过读取这些寄存器,操作系统可以了解设备的状态,是否准备好接收一个新的命令等。
6、资源分为:可抢占资源和不可抢占资源。存储器就是一类可抢占的资源,CD盘是不可抢占资源。
资源死锁的四个条件:
1)互斥条件。每个资源要么已经分配给了一个进程,要么就是可用的。
2)占有和等待条件。已经得到某个资源的进程可以再请求新的资源,且如果因请求资源而阻塞时,对已获资源保持不放。
3)不可抢占条件。已经分配给一个进程的资源不能强制性被抢占,它只能被占有它的进程显式地释放
4)环路等待条件。死锁发生时,系统中一定有由两个或两个以上的进程组成的一条环路,该环路中的每个进程都在等待着下一个进程所占有的资源。
解决死锁的方法:
1)鸵鸟算法----忽略问题
2)死锁检测和恢复
3)死锁避免----银行家算法
4)死锁预防----破坏资源死锁的四个条件
进程调度中"可抢占"和"非抢占"两种方式,哪一种系统的开销更大?可抢占式会引起系统的开销更大。可抢占式调度是严格保证任何时刻,让具有最高优先数(权)的进程占有处理机运行,因此增加了处理机调度的时机,引起为退出处理机的进程保留现场,为占有处理机的进程恢复现场等时间(和空间)开销增大。
7、存储结构有(按照访问速度从快到慢排列):寄存器,高速缓存,内存,磁盘和磁带。CPU的高速缓存一般由RAM组成。
RAM和ROM的区别:
RAM-RamdomAccessMemory易挥发性随机存取存储器,高速存取,读写时间相等,且与地址无关,如计算机内存等,计算机关闭电源后其内的信息将不在保存,再次开机需要重新装入。ROM-Read Only Memory只读存储器。断电后信息不丢失,如计算机启动用的BIOS芯片。存取速度很低,(较RAM而言)且不能改写。一般用它存储固定的系统软件和字库等。
8、文件描述符表,文件表和v-node表的关系:
请参考以下链接:http://www.cnblogs.com/zhaoyl/archive/2012/05/15/2502010.html
http://blog.chinaunix.net/uid-26430381-id-4200682.html
http://my.oschina.net/iuranus/blog/330397
9、X86体系结构在保护模式下有三种地址,它们的转换形式:虚拟地址(逻辑地址)先经过分段机制映射到线性地址,然后线性地址通过分页机制映射到物理地址。参考该文章:X86体系中保护模式下的内存访问机制_湛辉来。
10、Java的线程调度是基于优先级的抢先式调度,它总是选择高优先级的线程先执行。Thread提供了如下的基本线程控制方法:sleep (),线程暂停,让出CPU,使低优先级的线程运行;yield(),线程暂停,让出CPU,使同优先级的其他线程运行。如果不存在有机会运行的线程,yield()方法将直接返回,线程继续;join(),当前线程暂停,等待线程类对象运行结束。相同优先级的线程有可能采用分时调度也有可能是线程逐个运行,由具体JVM而定。
11、位示图是利用二进制的一位来表示磁盘中的一个盘块的使用情况。当其值为“0”时,表示对应的盘块空闲;为“1”时,表示已经分配。有的系统把"0"作为盘块已分配的标记,把“1”作为空闲标志。(它们的本质上是相同的,都是用一位的两种状态标志空闲和已分配两种情况。)磁盘上的所有盘块都有一个二进制位与之对应,这样,由所有盘块所对应的位构成一个集合,称为位示图。通常可用m*n个位数来构成位示图,并使m*n等于磁盘的总块数。方便磁盘空间的管理。
12、进程死锁相关问题:
1)某系统中有11台打印机,N个进程共享打印机资源,每个进程要求3台。当N的取值不超过____时,系统不会发生死锁。
当每个进程都获得了2台打印机且系统中剩余打印机不少于1台时,系统不会发生死锁,即11-2N≥1,由此知N≤5。
2)某系统中有3个并发进程,都需要同类资源4个,试问该系统不会发生死锁的最少资源数是____。
因系统中存在3个进程,且都需要同类资源4个,当系统中资源数等于10时,无论怎样分配资源,其中至少有一个进程可以获得4个资源,该进程可以顺利运行完毕,从而可以将分配给 它的资源归还给系统,其他进程也能顺利执行完成。若系统中资源数小于10,不妨设系统中有9个资源且每个进程都已获得3个资源,此时系统中已无空闲资源,当其中的任何一个进程 再次申请资源时将进入等待状态,其他进程的情况类似,此时出现死锁。
13、中断问题
当一个I/O设备完成交给它的工作时,它就产生一个中断,它是通过在分配给它的一条总线信号线上置起信号而产生中断的。中断信号导致CPU停止当前正在做的工作并且开始做其他的事情。地址线上的数字被用做指向一个称为中断向量的表格的索引。
从中断事件的性质出发,中断可以分为两大类:
1)强迫性中断事件:包括硬件故障中断,程序性中断,外部中断和输入输出中断等。
2)自愿性中断事件:是由正在运行的进程执行一条访管指令用以请求系统调用而引起的中断,这种中断也称为"访管中断"。对OS提出某种服务要求时发生的发生的中断,也可以称为软中断。如请求I/O,请求分配外设等等。
硬件故障中断:机器发生故障时产生的中断,如电源故障、奇偶校验错等。
程序性中断:程序执行时发生了程序性质的错误或出现了某些特定状态而产生的中断,如溢出、地址错,指令跟踪,目态下使用特权指令等。
外部中断:中央处理机外部的非通道式装置引起的中断,如时钟中断、控制台中断。
输入/输出中断:外设或通道操作正常完成或发生某种错误时产生的中断。如传输结束、设备错误等。
一般情况下,优先级的高低顺序依次为:硬件故障中断、自愿中断、程序性中断,外部中断和输入输出中断。自愿中断的断点是确定的,是正在运行程序所期待的事件。而强迫性中断的断点可能发生在任何位置。
14、操作系统的功能:处理机管理,存储器管理,设备管理,文件管理和作业管理等。其中的处理机管理就是进程管理。
操作系统根据调度算法分为三类:
1)批处理操作系统:吞吐量,周转时间,CPU利用率 批处理操作系统的主要优点是系统吞吐量大、资源利用率高。其缺点是交互能力较差、作业周转时间长。
2)交互式操作系统:响应时间,均衡性
3)实时性操作系统:满足截止时间,可预测性
实时操作系统的调度算法是抢占式的,因为要保证对事件的实时响应,需要事件响应进程及时获得CPU时间,采用抢占式调度算法可以保证优先级高的进程可以暂停优先级低的进行而自身获取CPU时间。
15、多线程的一些问题(两个线程,执行i++,i=0全局变量):
执行i++需要三个过程:
1)从内存读变量值到寄存器
2)寄存器的值加1
3)将寄存器的值写回内存
对于多线程的程序,访问冲突的问题是很普遍的,这回导致结果的不可预知性。
16、多进程多线程具体实现事宜:
1)join()
方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。
2)ThreadLocal
对象,每个Thread
对它都可以读写对应属性,但互不影响。你可以把ThreadLocal对象看成全局变量,但每个属性如local_school.student
都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal
内部会处理。可以理解为全局变量local_school
是一个dict
,不但可以用local_school.student
,还可以绑定其他变量。ThreadLocal
最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。
3)多进程的优点就是稳定性高,因为一个子进程崩溃了,不会影响主进程和其他子进程。(当然主进程挂了所有进程就全挂了,但是Master进程只负责分配任务,挂掉的概率低)。
多进程的缺点是创建进程的代价大,在Unix/Linux系统下,用fork
调用还行,在Windows下创建进程开销巨大。另外,操作系统能同时运行的进程数也是有限的,在内存和CPU的限制 下,如果有几千个进程同时运行,操作系统连调度都会成问题。
多线程的优缺点分析:多线程模式通常比多进程快一点,但是也快不到哪去,而且,多线程模式致命的缺点就是任何一个线程挂掉都可能直接造成整个进程崩溃,因为所有线程共享进程的内存。在Windows上,如果一个线程执行的代码出了问题,你经常可以看到这样的提示:“该程序执行了非法操作,即将关闭”,其实往往是某个线程出了问题,但是操作系统会强制结束整个进程。
4)切换作业是有代价的,比如从语文切到数学,要先收拾桌子上的语文书本、钢笔(这叫保存现场),然后,打开数学课本、找出圆规直尺(这叫准备新环境),才能开始做数学作业。操作系统在切换进程或者线程时也是一样的,它需要先保存当前执行的现场环境(CPU寄存器状态、内存页等),然后,把新任务的执行环境准备好(恢复上次的寄存器状态,切换内存页等),才能开始执行。这个切换过程虽然很快,但是也需要耗费时间。如果有几千个任务同时进行,操作系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种情况最常见的就是硬盘狂响,点窗口无反应,系统处于假死状态。
5)计算密集型任务及I/O密集型任务:
计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。
IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。
17、网络编程socket:
用TCP协议进行Socket编程在Python中十分简单,对于客户端,要主动连接服务器的IP和指定端口,对于服务器,要首先监听指定端口,然后,对每一个新的连接,创建一个线程或进程来处理。通常,服务器程序会无限运行下去。同一个端口,被一个Socket绑定了以后,就不能被别的Socket绑定了。
UDP的使用与TCP类似,但是不需要建立连接。此外,服务器绑定UDP端口和TCP端口互不冲突,也就是说,UDP的9999端口与TCP的9999端口可以各自绑定。
18、程序与进程的区别:
程序是指计算机指令的集合,以文件的形式存储在磁盘上,它是静态实体。
程序不能申请系统资源,也不能被系统调度,也不能作为独立的运行单位。
进程是一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。
进程是资源申请、调度和独立运行的单位。
19、磁带上的文件,一般只能采取“顺序存取”的方式。
当用磁盘来存储文件时,可以不按顺序地读取文件中的字节或记录,或者按照关键字而不是位置来存取记录。这种方式读取文件称作“随机存取文件”。
所以磁盘的话,既可以随机存储,也可以顺序存储。
磁盘读取数据是以盘块(block)为基本单位的。
20、并行程序与并发程序的区别与联系:
并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。
21、Spooling技术
它是关于慢速字符设备如何与计算机主机进行数据交换的一种技术,通常又称假脱机技术。
利用这种技术可把独占设备转变成共享的虚拟设备,从而提高独占设备的利用率和进程的推进速度。
输入进程SPI是模拟脱机输入时的外围控制机,它将用户要求处理的数据从输入设备通过输入缓冲区再送到输入井(磁盘上开辟的一块区域),
当CPU处理这些数据数据时,就直接从输入井读入内存。
输出进程SPO是模拟脱机输出时的外围控制机,把用户要求输出的数据,先从内存送到输出井,待输出设备空闲时,
再将输出井中的数据通过输出缓冲区(内存中一块区域)传送到输出设备上。
实例——利用打印机实现打印机共享
1、当用户进程请求打印输出时,SPOOLING系统立即同意为该进程执行打印输出,但并不是真正地把打印机分配给该用户进程,而只是为该进程做两项工作: 一项是由输出进程SPO在输出井中为之申请一个空闲的存储空间,并将要打印的数据传送其中存放;另一项工作就是由输出进程SPO再为用户进程申请一张空白的用户请求打印表,并将用户的打印请求填入其中,然后将该表挂到打印机的请求队列上。这时,如果还有另一个进程请求打印机时,则系统仍同意为该进程执行打印输出,当然,系统所做的工作仍是以上两项内容。
2、在打印机执行实际打印时,如果打印机空闲,输出进程SPO将从请求打印队列的队首取出一张打印表,根据打印表中的要求将要打印的数据从输出井传送到内存输出缓冲区,再传送到打印机打印。打印完后,输出进程SPO将再检查请求打印队列中是否还有待打印的请求表,若有则再取出一张请求打印表,将新的但因要求继续打印。如此反复,直到请求打印队列空为止,输出进程才将自己阻塞起来,并在下次再有打印请求时被唤醒。
22、DMA技术
DMA是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。要把外设的数据读入内存或把内存的数据传送到外设,一般都要通过CPU控制完成,
如CPU程序查询或中断方式。利用中断进行数据传送,可以大大提高CPU的利用率。但是采用中断传送有它的缺点,对于一个高速I/O设备,以及批量交换数据的情况,
只能采用DMA方式,才能解决效率和速度问题。DMA在外设与内存间直接进行数据交换,而不通过CPU,这样数据传送的速度就取决于存储器和外设的工作速度。
通常系统的总线是由CPU管理的。在DMA方式时,就希望CPU把这些总线让出来,即CPU连到这些总线上的线处于第三态--高阻状态,而由DMA控制器接管,
控制传送的字节数,判断DMA是否结束,以及发出DMA结束信号。
23、sleep()与wait()的区别
sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,
因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。
wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,
那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。
1、这两个方法来自不同的类分别是Thread和Object
2、最主要是sleep方法没有释放锁,而 wait 方法释放了锁,使得其他线程可以使用同步控制块或者方法。sleep不出让系统资源;
wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。
3、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)
4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
24、内存池、进程池、线程池
内存池介绍:
首先是创建内存池。这个过程的主要任务是预先分配足够大的内存,形成一个初步的“内存池”。分配内存,也就是用户请求内存时,会返回内存池中一块空闲的内存,并将其标志置为已使用,当然具体细节和方法有很多。释放内存时,不是真正地调用free或是delete的过程,而是把内存放回内存池的过程。在把内存放入内存池的同时,要把标志位置为空闲。最后在应用程序结束时,要把内存池销毁。这里主要做的工作就是把内存池中的每一块内存释放。
使用内存池的好处:
1、减少了内存碎片的产生。这个可以从创建内存池的过程中看出。我们在创建内存池时,分配的都是一块块比较整的内存块,这样可以减少内存碎片的产生。
2、提高了内存的使用效率。这个可以从分配内存和释放内存的过程中看出。每次的分配与释放并不是去调用系统提供的函数或是操作符去操作实际的内存,而是在复用内存池中的内存。
缺点就是很有可能会造成内存的浪费,原因也很明显,开始分配了一大块内存,不是全部都用得到的。
进程池与线程池的原理是差不多的:
其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。可能你也许会问:为什么要搞得这么麻烦,如果每当客户端有新的请求时,我就创建一个新的线程不就完了?这也许是个不错的方法,因为它能使得你编写代码相对容易一些,但你却忽略了一个重要的问题?那就是性能!就拿我所在的单位来说,我的单位是一个省级数据大集中的银行网络中心,高峰期每秒的客户端请求并发数超过100,如果为每个客户端请求创建一个新线程的话,那耗费的CPU时间和内存将是惊人的,如果采用一个拥有200个线程的线程池,那将会节约大量的系统资源,使得更多的CPU时间和内存用来处理实际的商业应用,而不是频繁的线程创建与销毁。
线程池应用的场所:
25、Windows总体结构
有4中用户模式进程:
1.固定的系统支持进程,如登陆进程,会话管理器进程。
2.服务进程,宿纳了windows服务,如进程管理器和假脱机服务。
3.用户应用程序,有6个类型:windows32位,windows64位,windows3.1 16位,ms-dos 16位,posix32位或者OS/2 32位。
4.环境子系统服务进程,实现了操作系统环境的部分支持。这里的环境是指操作系统展示给用户或者程序员的个性化部分。
在windows下,用户程序不能直接访问原始的windows服务,要通过一个或者多个子系统动态链接库。
windows内核组件包含:
1.windows执行体,包含基本的操作系统服务,如内存管理,进程和线程管理,安全性,I/O,网络,跨进程通信。
2.windows内核,是由一组底层的操作系统功能构成,如线程调度,终端和异常处理分发。以及处理器同步。提供了一组例程和基础对象。执行体的其他部分利用这些例程和对象实现更高层次的功能。
3.设备驱动程序,硬件设备驱动程序,也包含文件系统和网络驱动程序。其中硬件设备驱动程序将用户的I/O函数调用转化为特定的硬件设备请求。
4.硬件抽象层,指一层特殊代码,它把内核,设备驱动程序和windows执行体其他部分跟与平台相关的硬件差异隔离开来。
5.窗口和图形系统:实现了图形用户界面函数。
26、进程调度的算法
1.先来先服务调度算法
2.短作业优先调度
3.非抢占式优先权算法
4.抢占式优先权调度
5.高响应比优先调度算法
如果我们能为每个作业引入前面所述的动态优先权,并使作业的优先级随着等待时间的增加而以速率a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。
6.时间片轮转法
7.多级反馈队列调度算法
特点:应设置多个就绪队列,并为各个队列赋予不同的优先级。第一个队列的优先级最高,第二个队列次之,其余各队列的优先权逐个降低。该算法赋予各个队列中进程执行时间片的大小也各不相同,在优先权愈高的队列中,为每个进程所规定的执行时间片就愈小;
当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;
仅当第一队列空闲时,调度程序才调度第二队列中的进程运行。
二、面试内容
1、为什么引进进程
程序的执行顺序:
(1)顺序执行:顺序性、封闭性、可再现性
(2)并发执行:间断性、失去封闭性、不可再现性
在多道程序环境下程序的执行是并发的,这样程序就要失去封闭性,并且间断且不可再现。并发执行的三个特点决定通常的程序是不能被并发执行的,于是引入了进程。
2、进程的特征
(1)结构特征:每个进程都对应一个PCB(进程控制块)。程序段、数据段和PCB构成了进程实体。
(2)动态性:动态性是进程最基本的特征,因为进程的实质是进程实体的一次执行过程。
(3)并发性:进程的引入就是为了满足多道程序的并发执行的特征。
(4)独立性:进程是参与资源分配的基本单位(线程是被调度的基本单位)
(5)异步性:指进程被执行的速度和顺序具有不确定性,即进程按异步方式运行。
3、进程的状态
就绪状态:只差CPU就可以运行的进程
执行状态
阻塞状态:正在执行的进程遇到某个时间之后暂时不需要CPU了,就把CPU让出来并排到阻塞状态的进程队列中去。
4、PCB(进程控制块)的理解
PCB是进程存在的唯一标志。
PCB的作用:是让一个在多道程序环境下无法并发运行的程序成为一个能够独立地接受调度和运行的基本单位,从而使之成为能和其他进程并发运行的进程。
PCB的内容:进程标识符、CPU状态信息、进程调度信息、进程控制信息等。
PCB的组织方式:链接方式、索引方式
5、进程控制
进程的创建
1)引起进程创建的事件有:用户登录、作业调度、提供服务、应用请求
2)创建步骤:申请空白PCB、为新进程分配资源、初始化进程控制块、将新进程插入就绪
进程的终止
1)引起进程终止的事件有:正常结束、异常结束、外界干预
2)终止步骤:读进程状态、若被终止进程处于执行状态则表示该进程被终止后需要重新调度、若该进程有子孙进程则终止所有子孙进程、归还进程资源、移除队列中的PCB
进程的阻塞与唤醒
引起进程阻塞的事件:请求系统服务、启动某种操作、新数据尚未到达、无新工作可做
引起唤醒的事件:当被阻塞进程所期待的事件出现的,如系统服务完成、I/O操作完成、所期待数据已经到达
6、进程同步
(1)临界资源:某些共享资源仅允许一个进程使用,这就是临界资源。比如打印机、磁带机。
(2)临界区:每个进程中访问临界资源的那段代码叫做临界区。临界区是进程中的代码!!
为了查看当前有没有进程在访问临界资源,所以每个进程在进入临界区之前要执行一段检测代码,这段代码叫做进入区。在离开临界区后进程要标记下现在已经没有进程访问临界资源,这段代码叫做退出区。其他代码称为剩余区。
(3)同步(直接相互制约关系):一个进程到达了某点后,除非另一进程已经完成了某些操作,否则就不得不停下来等待这些操作的结束,这就是进程间的同步,有了同步后进程间就可以相互合作。
(4)互斥(间接相互制约关系):多个进程都想使用一个临界资源,但是不能同时使用,于是只好一个进程用完了才能给其他进程用,这就是进程互斥。某种意义上说进程互斥是进程同步的一个特殊情况。
实现同步的准则:
A. 空闲让进:当无进程处于临界区时,应允许一个请求进入临界区的进程立即进入自己的临界区
B. 忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待,以保证临界资源互斥访问
C. 有限等待:对要求访问临界资源的进程,应保证有限时间内进入自己的临界区,以免陷入“死等”
D. 让权等待:当进程不能进入自己的临界区时,应立即释放处理机,以免进程陷入“忙等”(忙等是指当一个进程在临界区,当其他进程欲进入临界区时,反复检测是否可以进入,即忙于等待临界区中的进程离开)
忙等待的互斥:
(1)屏蔽中断----把屏蔽中断的权力交给用户进程是不明智的。
(2)锁变量----可能还是会引发竞争条件
(3)严格轮换法----浪费CPU时间
(4)Peterson解法
解决忙等待的方法:
(5)睡眠与唤醒---sleep是一个将引起调用进程阻塞的系统调用,即被挂起,直到另外一个进程将其唤醒wakeup。
信号量:有两种操作,down和up(分别为一般化后的sleep和wakeup)。
down是先检查其值是否大于0,大于0将其减1并继续。若该值为0,则进程将睡眠。
up是对信号量的值加1。这些步骤是用于同步的。
还有一个信号量mutex是二元信号量,可以实现互斥。这是一种特殊的信号量,成为互斥量。
需要掌握线程同步的经典例子:生产者与消费者
(6)管程定义:管程是由一组数据以及定义在这个数据之上的对这组数据的操作组成的软件模块,这组操作能初始化并改变管程中的数据和同步进程。
7、进程间通信
进程通信就是进程间的数据交换。进程的互斥与进程的同步就是进程通信中的低级通信方式。Wait和signal操作成为低级通信原语。
高级通信方式是指以较高的效率传输大量数据的通信方式。
(1)共享存储器系统:是指互相通信的进程通过某些共享存储区或者共享数据结构进行通信。通过对共享存储区的读写来进行通信的方式属于高级通信方式,基于共享数据结构的通信方式属于低级通信方式。
(2)消息传递系统:进程间的数据交换是以格式化的消息为单位进行。具体又分直接通信方式和间接通信方式。
(3)管道通信:所谓的管道就是一个共享文件,它连接了一个读进程和一个写进程,让它们之间可以借助这个共享文件进行通信。写进程以字符流的形式将大量信息写入管道,读进程则在需要时从管道读出数据。
比较全面的总结如下:
# 管道( pipe ):
1.匿名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2.命名管道是通过网络完成通信,可靠的双向通信
# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
# 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
在Windows下的具体实现方式:Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替 文件句柄(HANDLE), 就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用 文件映射实现的, 所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。
# 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
# 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
Windows操作系统下的进程通信:
与上述唯一的差别是:没有消息队列,而是邮件槽。
剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个中介,Windows已建立的剪切(复制)-粘贴的机制为不同应用程序之间共享不同格式数据提供了一条捷径。但剪贴板只能在基于Windows的程序中使用,不能在网络上使用。
Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。
RPC既可以在单机不同进程间使用也可以在网络中使用。
8、线程理解
引入线程的原因:
创建进程的开销大、导致进程并发度不够,进程管理的开销大,进程间通信太麻烦,正是由于进程存在着这些缺点,致使引入线程。
线程的概念:
线程是进程中某个单一顺序的控制流,也被称为轻量进程,它是进程中的一个实体,是被系统独立调度和分派的基本单位。
用户级线程和内核支持线程:
用户级线程:仅存在用户空间,与内核无关。内核管理用户级线程对应的整个进程。它感觉不到用户级线程的存在。
好处:无需内核支持就可以实现多线程,线程的切换不需要陷入到内核,所以切换的开销小速度快。
缺点:进程的一个线程被阻塞后整个进程中的所有线程都被阻塞,并且无法享有多处理机带来的好处。(调度单位为进程)
内核支持线程:是由内核负责管理的,线程控制块也在内核中。所以线程的创建、切换、撤销等操作都是通过系统调用在内核中完成的。
好处:进程中的一个线程被阻塞之后该进程的其他线程还可以继续执行不会被阻塞。
缺点:即使是同一个进程内的不同线程之间的切换也要陷入内核,开销大。
多线程模型:
(1)多对一模型(多个用户级线程映射到一个内核线程)
优点:线程管理是在用户控件进行的,因而效率比较高。
缺点:进程的一个线程被阻塞后整个进程中的所有线程都被阻塞
(2)一对一模型(一个用户级线程映射到一个内核线程)
优点:进程中的一个线程被阻塞之后该进程的其他线程不会被阻塞,并发能力较强
缺点:开销大
(3)多对多模型(m个用户级线程映射到n个内核线程,m ≥ n)
特点:集二者之所长
9、三级调度:
(1)高级调度:又称为作业调度或长期调度
作业调度负责从外存上等候调度的作业中断则一个调入内存,并给这个作业分配资源,创建进程,然后挂到就绪队列上等待进程调度。
(2)中级调度:又称为进程对换或中程调度
中级调度负责把暂时无法运行的在内存中的进程调到外存中等待以减少内存空间的浪费,在内存有空闲时把外存中有条件运行的进程重新调入内存。所以引入中程调度主要是为了提高内存的利用率和系统的吞吐量。被中级调度处内存的进程处于挂起状态,中级调度的实质是对换。
(3)低级调度:又称为进程调度或短程调度,是最基本的一种调度
进程调度负责从内存的就绪队列上等候调度的进程中选择一个分配CPU给他,该进程的状态于是从就绪转变为运行。
调度队列:进程进入系统时,会被加入到作业队列中。驻留在内存中就绪的等待运行的进程被保存在就绪队列上,该队列一般用链表的形式来存储。等到特定的I/O设备的进程被放在特点的设备队列中,每个设备都有自己的设备队列。
10、调度方式:
1)非抢占式:即一个进程在执行过程中除了它自身有I/O请求等事件发生的情况外,其他进程不得中断它的执行,也就是不得抢夺他的CPU资源
2)抢占式:根据某种算法计算各个进程的优先权,优先权高的进程可以在优先权低的进程正在执行的时候抢夺其CPU资源
抢占的原则:
A. 给重要和紧急的进程赋予高的优先权
B. 短作业优先原则,即给短作业赋予高的优先权
C. 时间片原则,即给时间片完了的进程最低的优先权
11、调度算法:
批处理系统:吞吐量,周转时间,CPU利用率
1. 先来先服务算法(FCFS) 非抢占
2. 短作业优先算法(SJF) 非抢占(只有在所有的作业都可同时运行的情形下,该算法才是最优化的)
3. 最短剩余时间优先 抢占
交互式系统:响应时间,均衡性
1. 优先级调度算法
静态优先权算法:进程的优先权在整个运行期间不变
动态优先权算法:进程的优先权随着进程被调度的情况变化而变化,如随着进程等待的时间的增加而增加,这样可以防止有些优先级低的进程长期得不到运行
高响应比优先(动态):响应比 = (等待时间 + 运行时间)/ 运行时间
2.时间片轮转法(RR)
执行中的进程只要时间片(允许该进程在该时间段中运行)用完就要被就绪队列队首的那个进程抢占CPU。
3.多级队列调度算法
将就绪队列分成多个独立的队列,根据进程的属性和类型将一个进程永久地分配到一个队列中。每个队列都有自己的调度算法。队列之间有优先级差别,通常采用固定优先权可抢占调度
4.多级反馈队列调度算法
多级反馈队列调度算法将就绪队列分成多个队列,每个队列拥有的优先级不同,一个新的进程到达内存后,先被放到优先级高的队列中按时间片轮转法被调度执行,若在时间片用完后没有被执行完,那就被扔到优先级低的下一个队列去时间片轮转,相应的得到执行的机会就减少了。
优势:
1)保证了短作业的优先,让终端型用户满意
2)短批处理作业也能在一两个队列给的时间片里完成,周转时间仍然较短
3)长批处理作业虽然优先级较低,但经过前面几个队列后已经得到了部分执行,用户不必担心他长期处理
实时系统:满足截止时间,可预测性
|
先来先服务 |
短作业优先 |
高响应比优先 |
时间片轮转 |
多级反馈队列 |
是否可抢占 |
否 |
否 |
是 |
是 |
队列内算法不一定 |
|
|||||
优点 |
公平,实现简单 |
平均等待时间最少,效率最高 |
兼顾长短作业 |
兼顾长短作业 |
兼顾长短作业,有较好的相应时间,可行性强 |
缺点 |
不利于短作业 |
长作业容易饥饿,估计时间不确定 |
计算响应比的开销大 |
平均等待时间较长,上下文切换浪费时间 |
无 |
尤其适用于 |
|
批处理系统 |
|
交互式系统 |
|
13、基本分页式与基本分段式的存储管理模式:
分页 |
分段 |
信息的物理单位 |
信息的逻辑单位 |
分页目的是为了系统管理,提高内存利用率 |
分段的目的是为了能更好的满足用户需求 |
页大小固定且有系统决定 |
段长度补丁,不同段有不同段长,是有用户编写的程序的具体情况决定的 |
作业地址空间是一维的 |
作业地址空间是二维的 |
有内部碎片无外部 |
有外部碎片无内部 |
大型通用计算机系统多数采用段页式调度。
14、虚拟存储器
引入原因:解决内存不足的问题
1. 局部性原理
程序的局部性原理是指程序在执行的时候呈现出的局部性规律,也就是说一个短的时间范围内,程序的执行仅仅局限于某个部分,相应的他所访问的存储空间也局限于某个区域。
(1)时间局部性
程序中的某条指令一旦被执行,不久后可能再次被执行
(2)空间局部性
当程序访问了某个存储单元后,之后的时间内这个存储单元附近的存储单元也有可能被访问到,也就是程序在一段时间内访问的存储空间集中在一定的范围内。
2. 虚拟存储器的概念和特征
虚拟存储器是指有请求调入功能和置换功能的能从逻辑上对内存容量加以扩充的一种存储器系统,实际上是一个地址空间
虚拟存储器的特征
多次性(最重要的特征):与常规存储管理的一次性相反,虚拟存储器把一个作业分多次调入到内存
对换性:与常规存储管理的驻留性相反,在作业运行期间虚拟存储器允许将那些暂时不运行的程序或数据调出到外存的兑换区,到运行需要用到的时候才再调回到内存,提高了内存利用率
虚拟性:虚拟存储器对内存的扩充是逻辑上的
15、I/O控制方式:
(1)程序I/O方式
程序I/O方式中,I/O速度远远慢于CPU,致使CPU绝大部分时间都在测试I/O设备是否已经完成数据传输。
(2)中断驱动I/O控制方式
中断的优点:CPU和I/O可以并行工作,无需CPU不断测试,I/O设备会自行传输数据,等到一个数据传输完毕,I/O设备会发出一个中断来提醒CPU,CPU只需收到中断后处理下即可。
中断的缺点:由于中断I/O控制方式每传输几个字节(由数据缓冲寄存器大小决定)就发出一次中断,所以CPU还是会频繁的去处理中断。
中断处理程序的过程(仅指I/O完成时发出的中断):
1)唤醒被阻塞的驱动程序进程
2)保护被中断进程的CPU环境:将处理机状态字PSW和程序计数器PC等压栈。
3)转入相应的设备处理程序:测试中断源以确定引起中断的设备号
4)恢复被中断进程的现场:把当时压入栈保护的数据弹出恢复当时CPU执行的上下文
(3)直接存储器访问I/O控制方式(DMA)
用DMA控制器来控制一个数据块的传输,而CPU只需在一个数据块传输的开始阶段设置好传输所需的控制信息并在传输的结束阶段做进一步处理即可的传输控制方式。其基本思想是在I/O设备和内存间开启一个可以直接传输数据的通路
特点:
1)数据传输的基本单位是数据块
2)所传诵的数据时从设备直接送入内存,或者相反
3)仅在传送一个或多个数据块的开始和结束时,才需CPU干预,整块数据的传送是在控制器的控制下完成的。
(4)I/O通道控制方式
I/O通道实际上是一种特殊的处理机。相对于DMA对每个数据块的读写为单位的干预,减少为对一组数据库的读写及有关控制和管理为单位的干预。又可实现CPU、通道和I/O设备三者的并行操作。
通道与DMA方式的比较:
类似:都是以内存为中心,实现了内存和设备直接交换数据
区别:
1)DMA方式需要CPU来控制传输的数据块的大小、传输的内存,而通道方式中这些信息都是有通道来控制管理的。
2)每个DMA控制器对应一台设备与内存传递数据,而一个通道可以控制多台设备与内存的数据交换。
16、高速缓存与缓冲区的比较:
高速缓存是为了存放低速设备上经常要被访问到的数据的拷贝,如果需要访问的数据高速缓存中没有,那么还是要去访问低速设备的。
缓冲区是为了缓和高速设备和低速设备之间速度不匹配的矛盾而存在的,高速设备和低速设备通信每次都要经过缓冲区,高速设备不会直接去访问低速设备(因为不一定有拷贝)。
17、设备分配:
设备独立性:应用程序独立于具体使用的物理设备,它可以提高设备分配的灵活性和设备的利用率。
为了实现设备独立性而引入逻辑设备和物理设备这两个概念,而系统中需要设置一张逻辑设备表(LUT),其中每个表象中都有逻辑设备名、物理设备名和设备驱动程序入口地址。
设备独立性的优点:(1)设备分配时的灵活性、易于实现I/O重定向(2)提高设备资源利用率
18、多线程与多进程的区别
子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
用多进程时每个进程有自己的地址空间,线程则共享地址空间。所有其他区别都是由此而来的:(1)速度:线程产生的速度快,线程间的通信快,切换快等,因为它们在同一个地址空间内。(2)资源利用率:线程的资源利用率比较好也是因为它们在同一个地址空间内。(3)同步问题:线程使用公共变量/内存时需要使用同步机制,还是因为它们在同一个地址空间内。
19、 Linux中常用到的命令
更详细的介绍关注以下博客:http://blog.csdn.net/xiaoguaihai/article/details/8705992
显示文件目录命令ls
改变当前目录命令cd
建立子目录mkdir
删除子目录命令rmdir
删除文件命令RM
文件复制命令cp
获取帮助信息命令man
重定向与管道type
20、Linux文件属性有哪些?(共十位) -rw-r--r--
第一个短横处是文件类型识别符:-表示普通文件;c表示字符设备(character);b表示块设备(block);d表示目录(directory);l表示链接文件(link) 后面第一个三个连续的短横是用户权限位(User),第二个三个连续短横是组权限位(Group),第三个三个连续短横是其他权限位(Other)。每个权限位有三个权限,r(读权限),w(写权限),x(执行权限)。如果每个权限位都有权限存在,那么满权限的情况就是:-rwxrwxrwx;权限为空的情况就是- --- --- ---。
权限的设定可以用chmod命令,其格式位:chomod ugo+/-/=rwx filename/directory。
21、makefile文件的作用是什么?
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令。