操做系统是管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石。操做系统须要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操做网络与管理文件系统等基本事务。操做系统也提供一个让用户与系统交互的操做界面。 html
操做系统上运行的计算机程序一般由一个或一组进程组成。所以,本文便从进程开始提及! linux
如上图所示,进程包括三种状态:就绪态、运行态和阻塞态。详细说明以下: 程序员
注意:建立和退出不是进程的状态。阻塞也叫等待,等待和就绪的区别:等待是等待除CPU之外的资源,而就绪等待的是CPU资源。 web
1)就绪——执行:对就绪状态的进程,当进程调度程序按一种选定的策略从中选中一个就绪进程,为之分配了处理机后,该进程便由就绪状态变为执行状态; 算法
2)执行——等待:正在执行的进程因发生某等待事件而没法执行,则进程由执行状态变为等待状态,如进程提出输入/输出请求而变成等待外部设备传输信息的状态,进程申请资源(主存空间或外部设备)得不到知足时变成等待资源状态,进程运行中出现了故障(程序出错或主存储器读写错等)变成等待干预状态等等; 安全
3)等待——就绪:处于等待状态的进程,在其等待的事件已经发生,如输入/输出完成,资源获得知足或错误处理完毕时,处于等待状态的进程并不立刻转入执行状态,而是先转入就绪状态,而后再由系统进程调度程序在适当的时候将该进程转为执行状态; 服务器
4)执行——就绪:正在执行的进程,因时间片用完而被暂停执行,或在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行而被迫让出处理机时,该进程便由执行状态转变为就绪状态。 网络
详见快课以前分享的文章: 数据结构
进程与线程的图文描述多线程
以linux操做系统为例(window也相似),linux下进程间通讯方式以下:
1) 管道(Pipe)及有名管道(namedpipe):管道可用于具备亲缘关系进程间的通讯,有名管道克服了管道没有名字的限制,所以,除具备管道所具备的功能外,它还容许无亲缘关系进程间的通讯;
2) 信号(Signal):信号是比较复杂的通讯方式,用于通知接受进程有某种事件发生,除了用于进程间通讯外,进程还能够发送信号给进程自己;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又可以统一对外接口,用sigaction函数从新实现了signal函数);
3) 报文(Message)队列(消息队列):消息队列是消息的连接表,包括Posix消息队列systemV消息队列。有足够权限的进程能够向队列中添加消息,被赋予读权限的进程则能够读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
4) 共享内存:使得多个进程能够访问同一块内存空间,是最快的可用IPC形式。是针对其余通讯机制运行效率较低而设计的。每每与其它通讯机制,如信号量结合使用,来达到进程间的同步及互斥。
5) 信号量(semaphore):主要做为进程间以及同一进程不一样线程之间的同步手段。
6) 套接口(Socket):更为通常的进程间通讯机制,可用于不一样机器之间的进程间通讯。起初是由Unix系统的BSD分支开发出来的,但如今通常能够移植到其它类Unix系统上:Linux和SystemV的变种都支持套接字。
线程同步的方式主要有如下四种:临界区(CriticalSection)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别。
他们的主要区别和特色以下:
1) 临界区:经过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只容许一个线程对共享资源进行访问,若是有多个线程试图访问公共资源,那么在有一个线程进入后,其余试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其余线程才能够抢占。
2) 互斥量:采用互斥对象机制。只有拥有互斥对象的线程才有访问公共资源的权限,由于互斥对象只有一个,因此能保证公共资源不会同时被多个线程访问。互斥不只能实现同一应用程序的公共资源安全共享,还能实现不一样应用程序的公共资源安全共享。
3) 信号量:它容许多个线程在同一时刻访问同一资源,可是须要限制在同一时刻访问此资源的最大线程数目。
4) 事件:经过通知操做的方式来保持线程的同步,还能够方便实现对多个线程的优先级比较的操做。
(换种方式说即:用户线程与内核线程的区别)
线程的实现能够分为两类:用户级线程(User-LevelThread)和内核线线程(Kernel-LevelThread),后者又称为内核支持的线程或轻量级进程。
在多线程操做系统中,各个系统的实现方式并不相同,在有的系统中实现了用户级线程,有的系统中实现了内核级线程。
用户线程:指不须要内核支持而在用户程序中实现的线程,其不依赖于操做系统核心,应用进程利用线程库提供建立、同步、调度和管理线程的函数来控制用户线程。不须要用户态/核心态切换,速度快,操做系统内核不知道多线程的存在,所以一个线程阻塞将使得整个进程(包括它的全部线程)阻塞。因为这里的处理器时间片分配是以进程为基本单位,因此每一个线程执行的时间相对减小。
内核线程:由操做系统内核建立和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程因为I/O操做而阻塞,不会影响其它线程的运行。
如下是用户级线程和内核级线程的区别:
1) 内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。
2) 用户级线程的建立、撤消和调度不须要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的建立、撤消和调度都需OS内核提供支持,并且与进程的建立、撤消和调度大致是相同的。
3) 用户级线程执行系统调用指令时将致使其所属进程被中断,而内核支持线程执行系统调用指令时,只致使该线程被中断。
4) 在只有用户级线程的系统内,CPU调度仍是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。
5) 用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是能够运行在任何状态下的程序。
在讲述用户态和核心态的区别以前,咱们先要说说“特权级”的概念。
熟悉Unix/Linux系统的人都知道,咱们建立一个子进程时,是经过调用fork函数来实现的。事实上,fork的工做其实是以系统调用的方式完成进程建立功能的,具体的工做是由sys_fork负责实施。对于任何操做系统来讲,建立一个新的进程都是属于核心功能,由于它要作不少底层细致地工做,消耗系统的物理资源,好比分配物理内存,从父进程拷贝相关信息,拷贝设置页目录页表等等,这些显然不能随便让哪一个程序就能去作,因而就天然引出特权级别的概念,显然,最关键性的权力必须由高特权级的程序来执行,这样才能够作到集中管理,减小有限资源的访问和使用冲突。
特权级显然是很是有效的管理和控制程序执行的手段,所以在硬件上对特权级作了不少支持,就Intelx86架构的CPU来讲一共有0~3四个特权级,0级最高,3级最低,硬件上在执行每条指令时都会对指令所具备的特权级作相应的检查,相关的概念有CPL、DPL和RPL,这里再也不过多阐述。硬件已经提供了一套特权级使用的相关机制,软件天然就是好好利用的问题,这属于操做系统要作的事情,对于Unix/Linux来讲,只使用了0级特权级和3级特权级。也就是说在Unix/Linux系统中,一条工做在0级特权级的指令具备了CPU能提供的最高权力,而一条工做在3级特权级的指令具备CPU提供的最低或者说最基本权力。
OK,有了上面对“特权级”概念的了解,就能更直观的了解用户态和核心态的区别。内核态与用户态是操做系统的两种运行级别,,当程序运行在3级特权级上时,就能够称之为运行在用户态,由于这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当程序运行在0级特权级上时,就能够称之为运行在内核态。运行在用户态下的程序不能直接访问操做系统内核数据结构和程序。当咱们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其须要操做系统帮助完成某些它没有权力和能力完成的工做时就会切换到内核态。一般来讲,如下三种状况会致使用户态到内核态的切换:
1) 系统调用
这是用户态进程主动要求切换到内核态的一种方式,用户态进程经过系统调用申请使用操做系统提供的服务程序完成工做,好比前例中fork()实际上就是执行了一个建立新进程的系统调用。而系统调用的机制其核心仍是使用了操做系统为用户特别开放的一个中断来实现,例如Linux的int80h中断。
2) 异常
当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换处处理此异常的内核相关程序中,也就转到了内核态,好比缺页异常。
3) 外围设备的中断
当外围设备完成用户请求的操做后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,若是先前执行的指令是用户态下的程序,那么这个转换的过程天然也就发生了由用户态到内核态的切换。好比硬盘读写操做完成,系统会切换到硬盘读写的中断处理程序中执行后续操做等。
这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用能够认为是用户进程主动发起的,异常和外围设备中断则是被动的。
操做系统中,每一个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存在于内核空间。当进程在用户空间运行时,cpu堆栈指针寄存器里面的内容是用户堆栈地址,使用用户栈;当进程在内核空间时,cpu堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。
内核栈是内存中属于操做系统空间的一块区域,其主要用途为:
1) 保存中断现场,对于嵌套中断,被中断程序的现场信息依次压入系统栈,中断返回时逆序弹出;
2) 保存操做系统子程序间相互调用的参数、返回值、返回点以及子程序(函数)的局部变量。
用户栈是用户进程空间中的一块区域,用于保存用户进程的子程序间相互调用的参数、返回值、返回点以及子程序(函数)的局部变量。
PS:那么为何不直接用一个栈,何须浪费那么多的空间呢?
1) 若是只用系统栈。系统栈通常大小有限,若是中断有16个优先级,那么系统栈通常大小为15(只需保存15个低优先级的中断,另外一个高优先级中断处理程序处于运行),但用户程序子程序调用次数可能不少,那样15次子程序调用之后的子程序调用的参数、返回值、返回点以及子程序(函数)的局部变量就不能被保存,用户程序也就没法正常运行了。
2) 若是只用用户栈。咱们知道系统程序须要在某种保护下运行,而用户栈在用户空间(即cpu处于用户态,而cpu处于核心态时是受保护的),不能提供相应的保护措施(或至关困难)。
首先介绍一个概念“池化技术”。池化技术一言以蔽之就是:提早保存大量的资源,以备不时之需以及重复使用。池化技术应用普遍,如内存池,线程池,链接池等等。内存池相关的内容,建议看看Apache、Nginx等开源web服务器的内存池实现。
因为在实际应用当作,分配内存、建立进程、线程都会设计到一些系统调用,系统调用须要致使程序从用户态切换到内核态,是很是耗时的操做。所以,当程序中须要频繁的进行内存申请释放,进程、线程建立销毁等操做时,一般会使用内存池、进程池、线程池技术来提高程序的性能。
线程池:线程池的原理很简单,相似于操做系统中的缓冲区的概念,它的流程以下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当须要一个开辟一个线程去作具体的工做时,就会唤醒线程池中的某一个睡眠线程,让它去作具体工做,当工做完成后,线程又处于睡眠状态,而不是将线程销毁。
进程池与线程池同理。
内存池:内存池是指程序预先从操做系统申请一块足够大内存,此后,当程序中须要申请内存的时候,不是直接向操做系统申请,而是直接从内存池中获取;同理,当程序释放内存的时候,并不真正将内存返回给操做系统,而是返回内存池。当程序退出(或者特定时间)时,内存池才将以前申请的真正内存释放。
计算机系统中,若是系统的资源分配策略不当,更常见的多是程序员写的程序有错误等,则会致使进程因竞争资源不当而产生死锁的现象。
产生死锁的缘由主要是:
1) 由于系统资源不足。
2) 进程运行推动的顺序不合适。
3) 资源分配不当等。
若是系统资源充足,进程的资源请求都可以获得知足,死锁出现的可能性就很低,不然就会因争夺有限的资源而陷入死锁。其次,进程运行推动顺序与速度不一样,也可能产生死锁。
产生死锁的四个必要条件:
1) 互斥条件:一个资源每次只能被一个进程使用。
2) 请求与保持条件:一个进程因请求资源而阻塞时,对已得到的资源保持不放。
3) 不剥夺条件:进程已得到的资源,在末使用完以前,不能强行剥夺。
4) 循环等待条件:若干进程之间造成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不知足,就不会发生死锁。
死锁的解除与预防:
理解了死锁的缘由,尤为是产生死锁的四个必要条件,就能够最大可能地避免、预防和解除死锁。因此,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何肯定资源的合理分配算法,避免进程永久占据系统资源。
此外,也要防止进程在处于等待状态的状况下占用资源,在系统运行过程当中,对进程发出的每个系统可以知足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,不然予以分配。所以,对资源的分配要给予合理的规划。
几种进程调度算法:
1、先来先服务和短做业(进程)优先调度算法
1.先来先服务调度算法。先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于做业调度,也可用于进程调度。FCFS算法比较有利于长做业(进程),而不利于短做业(进程)。由此可知,本算法适合于CPU繁忙型做业,而不利于I/O繁忙型的做业(进程)。
2.短做业(进程)优先调度算法。短做业(进程)优先调度算法(SJ/PF)是指对短做业或短进程优先调度的算法,该算法既可用于做业调度,也可用于进程调度。但其对长做业不利;不能保证紧迫性做业(进程)被及时处理;做业的长短只是被估算出来的。
2、高优先权优先调度算法
1.优先权调度算法的类型。为了照顾紧迫性做业,使之进入系统后便得到优先处理,引入了最高优先权优先(FPF)调度算法。此算法常被用在批处理系统中,做为做业调度算法,也做为多种操做系统中的进程调度,还能够用于实时系统中。当其用于做业调度,将后备队列中若干个优先权最高的做业装入内存。当其用于进程调度时,把处理机分配给就绪队列中优先权最高的进程,此时,又能够进一步把该算法分红如下两种:
1) 非抢占式优先权算法
2) 抢占式优先权调度算法(高性能计算机操做系统)
2.优先权类型
对于最高优先权优先调度算法,其核心在于:它是使用静态优先权仍是动态优先权,以及如何肯定进程的优先权。
3.高响应比优先调度算法
为了弥补短做业优先算法的不足,咱们引入动态优先权,使做业的优先等级随着等待时间的增长而以速率a提升。该优先权变化规律可描述为:优先权=(等待时间+要求服务时间)/要求服务时间;即=(响应时间)/要求服务时间
3、基于时间片的轮转调度算法
1.时间片轮转法。时间片轮转法通常用于进程调度,每次调度,把CPU分配队首进程,并令其执行一个时间片。当执行的时间片用完时,由一个记时器发出一个时钟中断请求,该进程被中止,并被送往就绪队列末尾;依次循环。
2.多级反馈队列调度算法多级反馈队列调度算法多级反馈队列调度算法,没必要事先知道各类进程所须要执行的时间,它是目前被公认的一种较好的进程调度算法。其实施过程以下:
1) 设置多个就绪队列,并为各个队列赋予不一样的优先级。在优先权越高的队列中,为每一个进程所规定的执行时间片就越小。
2) 当一个新进程进入内存后,首先放入第一队列的末尾,按FCFS原则排队等候调度。若是他能在一个时间片中完成,即可撤离;若是未完成,就转入第二队列的末尾,在一样等待调度……如此下去,当一个长做业(进程)从第一队列依次将到第n队列(最后队列)后,便按第n队列时间片轮转运行。
3) 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1到第(i-1)队列空时,才会调度第i队列中的进程运行,并执行相应的时间片轮转。
4) 若是处理机正在处理第i队列中某进程,又有新进程进入优先权较高的队列,则此新队列抢占正在运行的处理机,并把正在运行的进程放在第i队列的队尾。
1) 块式管理
把主存分为一大块、一大块的,当所需的程序片段不在主存时就分配一块主存空间,把程序片段载入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会形成很大的浪费,但时易于管理。
2) 页式管理
把主存分为一页一页的,每一页的空间要比一块一块的空间小不少,显然这种方法的空间利用率要比块式管理高不少。
3) 段式管理
把主存分为一段一段的,每一段的空间又要比一页一页的空间小不少,这种方法在空间利用率上又比页式管理高不少,可是也有另一个缺点。一个程序片段可能会被分为几十段,这样不少时间就会被浪费在计算每一段的物理地址上(计算机最耗时间的你们都知道是I/O吧)。
4) 段页式管理。(如今经常使用)
结合了段式管理和页式管理的优势。把主存分为若干页,每一页又分为若干段。
内存的连续分配方式有:单一连续分配、固定分区分配、动态分区分配以及动态重定位分区分配四种方式。 1) 单一连续分配:只能用于单用户、单任务的操做系统中。
2) 固定分区分配:可运行多道程序的存储管理方式。
3) 动态分区分配:根据进程的实际须要,动态地为之分配内存空间。
4) 可重定位分区分配:必须把一个系统或用户程序装入一连续的内存空间。
1) 静态连接就是在编译连接时直接将须要的执行代码拷贝到调用处,优势就是在程序发布的时候就不须要的依赖库,也就是再也不须要带着库一块发布,程序能够独立执行,可是体积可能会相对大一些。
2) 动态连接就是在编译的时候不直接拷贝可执行代码,而是经过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操做系统,操做系统负责将须要的动态库加载到内存中,而后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时链接的目的。优势是多个程序能够共享同一段代码,而不须要在磁盘上存储多个拷贝,缺点是因为是运行时加载,可能会影响程序的前期执行性能。
基本分页储存管理方式具备以下特征:
1) 一次性。要求将做业所有装入内存后方能运行。许多做业在每次运行时,并不是其所有程序和数据都要用到。若是一次性地装入其所有程序,形成内存空间的浪费。
2) 驻留性。做业装入内存后,便一直驻留在内存中,直至做业运行结束。尽管运行中的进程会因I/O而长期等待,或有的程序模块在运行过一次后就再也不须要(运行)了,但它们都仍将继续占用宝贵的内存资源。
请求分页储存管理是实现虚拟存储器的一种经常使用方式,它是在基本分页储存管理的基础上实现的。其基本思想是:在进程开始运行以前,仅装入当前要执行的部分页面便可运行;在执行过程当中,可以使用请求调入中断动态装入要访问但又不在内存的页面;当内存空间已满,而又须要装入新的页面时,者根据置换功能适当调出某个页面,以便腾出空间而装入新的页面。为实现请求分页,须要必定的硬件支持,包括:页表机制、缺页中断机构、地址变换机构。
分段和分页其实都是一种对地址的划分或者映射的方式。二者的区别主要有如下几点:
1) 页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提升内存的利用率;或者说,分页仅仅是因为系统管理的须要,而不是用户的须要(也是对用户透明的)。段是信息的逻辑单位,它含有一组其意义相对完整的信息(好比数据段、代码段和堆栈段等)。分段的目的是为了能更好的知足用户的须要(用户也是可使用的)。
2) 页的大小固定且由系统肯定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,于是一个系统只能有一种大小的页面。段的长度却不固定,决定于用户所编写的程序,一般由编辑程序在对源程序进行编辑时,根据信息的性质来划分。
3) 分页的做业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符(线性地址的16进制表示),便可表示一地址。分段的做业地址空间是二维的,程序员在标识一个地址时,既需给出段名(好比数据段、代码段和堆栈段等),又需给出段内地址。
4) 页和段都有存储保护机制。但存取权限不一样:段有读、写和执行三种权限;而页只有读和写两种权限。
1) 最佳置换算法(OPT)(理想置换算法)
这是一种理想状况下的页面置换算法,但其实是不可能实现的。该算法的基本思想是:发生缺页时,有些页面在内存中,其中有一页将很快被访问(也包含紧接着的下一条指令的那页),而其余页面则可能要到十、100或者1000条指令后才会被访问,每一个页面均可以用在该页面首次被访问前所要执行的指令数进行标记。最佳页面置换算法只是简单地规定:标记最大的页应该被置换。这个算法惟一的一个问题就是它没法实现。当缺页发生时,操做系统没法知道各个页面下一次是在何时被访问。虽然这个算法不可能实现,可是最佳页面置换算法能够用于对可实现算法的性能进行衡量比较。
2) 先进先出置换算法(FIFO)
最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,老是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最先调入内存的页,其再也不被使用的可能性比刚调入内存的可能性大。创建一个FIFO队列,收容全部在内存中的页。被置换页面老是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。
这种算法只是在按线性顺序访问地址空间时才是理想的,不然效率不高。由于那些常被访问的页,每每在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。
FIFO的另外一个缺点是,它有一种异常现象,即在增长存储块的状况下,反而使缺页中断率增长了。固然,致使这种异常现象的页面走向其实是不多见的。
3) 最近最久未使用(LRU)算法
FIFO算法和OPT算法之间的主要差异是,FIFO算法利用页面进入内存后的时间长短做为置换依据,而OPT算法的依据是未来使用页面的时间。若是以最近的过去做为不久未来的近似,那么就能够把过去最长一段时间里未曾被使用的页面置换掉。它的实质是,当须要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。这种算法就称为最久未使用算法(LeastRecentlyUsed,LRU)。LRU算法是与每一个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它一般是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在须要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。
1) 并发(concurrence)
并行性与并发性这两个概念是既类似又区别的两个概念。并行性是指两个或者多个事件在同一时刻发生,这是一个具备微观意义的概念,即在物理上这些事件是同时发生的;而并发性是指两个或者多个事件在同一时间的间隔内发生,它是一个较为宏观的概念。在多道程序环境下,并发性是指在一段时间内有多道程序在同时运行,但在单处理机的系统中,每一时刻仅能执行一道程序,故微观上这些程序是在交替执行的。应当指出,一般的程序是静态实体,它们是不能并发执行的。为了使程序能并发执行,系统必须分别为每一个程序创建进程。进程,又称任务,简单来讲,是指在系统中能独立运行并做为资源分配的基本单位,它是一个活动的实体。多个进程之间能够并发执行和交换信息。一个进程在运行时须要运行时须要必定的资源,如cpu,存储空间,及i/o设备等。在操做系统中引入进程的目的是使程序能并发执行。
2) 共享(sharing)
所谓共享是指,系统中的资源可供内存中多个并发执行的进程共同使用。因为资源的属性不一样,故多个进程对资源的共享方式也不一样,能够分为:互斥共享方式和同时访问方式。
3) 虚拟(virtual)
是指经过技术吧一个物理实体变成若干个逻辑上的对应物。在操做系统中虚拟的实现主要是经过分时的使用方法。显然,若是n是某一个物理设备所对应的虚拟逻辑设备数,则虚拟设备的速度必然是物理设备速度的1/n。
4) 异步(asynchronism)
在多道程序设计环境下,容许多个进程并发执行,因为资源等因素的限制,一般,进程的执行并不是“一鼓作气”,而是以“走走停停”的方式运行。内存中每一个进程在什么时候执行,什么时候暂停,以怎样的方式向前推动,每道程序总共须要多少时间才能完成,都是不可预知的。或者说,进程是以一步的方式运行的。尽管如此,但只要运行环境相同,做业通过屡次运行,都会得到彻底相同的结果。
直接存储器访问(DirectMemoryAccess,DMA)是计算机科学中的一种内存访问技术。它容许某些计算机内部的硬件子系统(电脑外设),能够独立地直接读写系统存储器,而不需绕道中央处理器(CPU)。在同等程度的处理器负担下,DMA是一种快速的数据传送方式。不少硬件的系统会使用DMA,包含硬盘控制器、绘图显卡、网卡和声卡。
SPOOLing(即外部设备联机并行操做),即SimultaneousPeripheralOperationOn-Line的缩写,它是关于慢速字符设备如何与计算机主机交换信息的一种技术,一般称为“假脱机技术”。
1) 连续分配
连续分配:建立文件时,分配一组连续的块;FAT中每一个文件只要一项,说明起始块和文件的长度。对顺序文件有利。
优势:
简单。适用于一次性写入的操做
支持顺序存取和随机存取,顺序存取速度快
所需的磁盘寻道次数和寻道时间最少(由于因为空间的连续性,当访问下一个磁盘块时,通常无需移动磁头,当须要磁头移动,只须要移动一个磁道。
缺点:
文件不能动态增加(可能文件末尾处的空块已经分配给别的文件)
不利于文件插入和删除
外部碎片问题(反复增删文件后),使得很难找到空间大小足够的连续块。进行紧缩
在建立文件时声明文件的大小。
2) 链式分配
链式分配:一个文件的信息存放在若干不连续的物理块中,各块之间经过指针链接,前一个物理块指向下一个物理块。FAT中每一个文件一样只须要一项,包括文件名、起始块号和最后块号。任何一个自由块均可以加入到链中。
优势:
提升了磁盘空间利用率,不存在外部碎片问题
有利于文件插入和删除
有利于文件动态扩充
缺点:
存取速度慢,通常仅适于对信息的顺序存取,不适于随机存取:查找某一个块必须从头开始沿指针进行。
可靠性问题,如指针出错;更多的寻道次数和寻道时间
连接指针占用必定的空间,将多个块组成簇(cluster),按簇进行分配而不是按块进行分配(增长了磁盘碎片)。
3)索引分配
索引分配:每一个文件在FAT中有一个一级索引,索引包含分配给文件的每一个分区的入口。文件的索引保存在一个单独的块中。FAT中该文件的入口指向这一块。
优势:
保持了连接结构的优势,又解决了其缺点:按块分配能够消除外部碎片,按大小可变的分区分配能够提升局部性。索引分配支持顺序访问文件和直接访问文件,是广泛采用的一种方式。
知足了文件动态增加、插入删除的要求(只要有空闲块)
也能充分利用外存空间
缺点:
较多的寻道次数和寻道时间.
索引表自己带来了系统开销,如:内外存空间,存取时间