操做系统知识总结

操做系统知识总结java

http://blog.csdn.net/houzuoxin/article/details/38957969c++

1. 进程的有哪几种状态,状态转换图,及致使转换的事件。程序员

状态:算法

1)就绪状态  进程已得到除处理机外的所需资源,等待分配处理机资源,只要分配到CPU就可执行。在某一时刻,可能有若干个进程处于该状态。   安全

2)运行状态   占用处理机资源运行,处于此状态的进程的数目小于等于CPU的数目。   网络

3)阻塞状态  因为进程等待某种条件(如I/O操做或进程同步),在条件知足以前没法继续执行。该事件发生前即便把处理机分配给该进程,也没法运行。多线程

 转换解释:从状态转换图中,存在四种状态转换。并发

当进程调度程序从就绪队列中选取一个进程投入运行时引发转换1;异步

正在执行的进程如因时间片用完而被暂停执行就会引发转换2;socket

正在执行的进程因等待的事件还没有发生而没法执行(如进程请求完成I/O)会引去转换3;

当进程等待的事件发生时(如I/O完成)则会引发转换4。

事件:就绪队列非空,则一个进程的转换3会当即引去另外一个进程的转换1。这是由于一个进程发生转换3意味着正在执行的进程由执行状态变为阻塞状态,这时处理机空闲,进程调度程序必然会从就绪队列中选取一个进程并将它投入运行,所以只要就绪队列非空,一个进程的转换3能当即引发一个进程的转换1。

 

2. 进程与线程的区别。dll是否有独立的堆栈? 

进程是具备必定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程本身基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),可是它可与同属一个进程的其余的线程共享进程所拥有的所有资源. 

一个线程能够建立和撤销另外一个线程;同一个进程中的多个线程之间能够并发执行 

    进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操做系统就帮你建立了一个主线程。每一个线程有本身的堆栈。 DLL(动态链接库)中有没有独立的堆栈,这个问题很差回答,或者说这个问题自己是否有问题。由于DLL中的代码是被某些线程所执行,只有线程拥有堆栈,若是DLL中的代码是EXE中的线程所调用,那么这个时候是否是说这个DLL没有本身独立的堆栈?若是DLL中的代码是由DLL本身建立的线程所执行,那么是否是说DLL有独立的堆栈?以上讲的是堆栈,若是对于堆来讲,每一个DLL有本身的堆,因此若是是从DLL中动态分配的内存,最好是从DLL中删除,若是你从DLL中分配内存,而后在EXE中,或者另一个DLL中删除,颇有可能致使程序崩溃。                 

另进程和程序的区别:进程即运行中的程序,从中便可知,进程是在运行的,程序是非运行的,固然本质区别就是动态和静态的区别。程序能够存在外存中,也能够存在内存中

 

3. 进程通讯的几种方式。

管道( pipe ):管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备亲缘关系的进程间使用。进程的亲缘关系一般是指父子进程关系。

有名管道 (named pipe) : 有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的通讯。

信号量( semophore ) : 信号量是一个计数器,能够用来控制多个进程对共享资源的访问。它常做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做为进程间以及同一进程内不一样线程之间的同步手段。

消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

信号 ( signal ) : 信号是一种比较复杂的通讯方式,用于通知接收进程某个事件已经发生。

共享内存( shared memory ) :共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,但多个进程均可以访问。共享内存是最快的 IPC 方式,它是针对其余进程间通讯方式运行效率低而专门设计的。它每每与其余通讯机制,如信号量,配合使用,来实现进程间的同步和通讯。

套接字( socket ) : 套解字也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样及其间的进程通讯。

 

 

4. 线程同步几种方式。(必定要会写生产者、消费者问题,彻底消化理解)

临界区(CCriticalSection):经过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。

事件(CEvent):为协调共同对一个共享资源的单独访问而设计的。

互斥量(CMutex):为控制一个具备有限数量用户资源而设计。

信号量(CSemaphore):用来通知线程有一些事件已发生,从而启动后继任务的开始。

  生产者、消费者问题

      Var mutex,empty,full:semaphore:=1,n,0;  // 定义三个信号量

    buffer:array[0,...,n-1]of item;  // 定义缓冲池,容量为n

    in,out:integer:=0,0;

    begin

        parbegin

            proceducer:begin // 生产者

                    repeat

                    producer an item nextp; // 生产一个产品 .

                    wait(empty);   // 申请一个空缓冲区

                    wait(mutex);  // 申请缓冲池的使用权

                    buffer(in):=nextp; // 将产品放入缓冲池中

                    in:=(in+1)mod n;  // 下一个空缓冲区地址

                    signal(mutex);  //释放缓冲池使用权

                    signal(full);  // 释放一个满缓冲区

                    until false;

                end

            consumer:begin

                    repeat

                    wait(full);

                    wait(mutex);

                    nextc:=buffer(out);

                    out:=(out+1)mod n;

                    signal(mutex);

                    signal(empty);

                    consumer the item in nextc;

                    until false;

                end

        parend

    end

nextp 应该是next proceducer的意思吧

nextc 应该是next consumer

貌似也不是什么变量,属于语言描述而已

下面的消费者也是差很少的。

至于生产者进程如何被阻塞和唤醒,由于程序中有一个 repeat语句,因此进程不断测试缓冲池是否有空缓冲区,以及缓冲池是否有其余进程使用。若两个条件不知足,则进入阻塞队列等待。若某一时刻两个条件都能知足,则能唤醒该进程。

    信号量:

    只支持两种操做,wait()和signal(),也叫作P、V操做,这两个操做是

原子操做,不会被打断。信号量机制有如下几种:

1.整型信号量--------------------一个整数,只能由PV操做对其加减

2.记录型信号量------------------在1的基础上种了一个链表,记录请求该资源的线程,解决1中没有让权等待的问题

3.AND信号量---------------------1和2只是对一个资源,而这个机制能解决一次请求多个资源的状况

4.通常信号量--------------------这是最通常的信号量机制,可以表示以上几种,表示方法也比较特殊,见操做系统

    3和4又属于信号量集机制。

5. 线程的实现方式. (也就是用户线程与内核线程的区别)

用户线程与内核线程的区别

根据操做系统内核是否对线程可感知,能够把线程分为内核线程和用户线程。

内核线程创建和销毁都是由操做系统负责、经过系统调用完成的,操做系统在调度时,参考各进程内的线程运行状况作出调度决定,若是一个进程中没有就绪态的线程,那么这个进程也不会被调度占用CPU。

和内核线程相对应的是用户线程,用户线程指不须要内核支持而在用户程序中实现的线程,其不依赖于操做系统核心,用户进程利用线程库提供建立、同步、调度和管理线程的函数来控制用户线程。用户线程多见于一些历史悠久的操做系统,例如Unix操做系统,不须要用户态/核心态切换,速度快,操做系统内核不知道多线程的存在,所以一个线程阻塞将使得整个进程(包括它的全部线程)阻塞。因为这里的处理器时间片分配是以进程为基本单位,因此每一个线程执行的时间相对减小为了在操做系统中加入线程支持,采用了在用户空间增长运行库来实现线程,这些运行库被称为“线程包”,用户线程是不能被操做系统所感知的。

引入用户线程,具体而言,有如下四个方面的优点:

(1)能够在不支持线程的操做系统中实现。

(2)建立和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。

(3)容许每一个进程定制本身的调度算法,线程管理比较灵活。

(4)线程可以利用的表空间和堆栈空间比内核级线程多。

用户线程的缺点主要有如下两点:

(1)同一进程中只能同时有一个线程在运行,若是有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。

(2)页面失效也会产生相似的问题。

内核线程的优缺点恰好跟用户线程相反。实际上,操做系统可使用混合的方式来实现线程。

 

Java实现线程的方式有三种:

(1)继承Thread类,重写run函数

建立:

class xx extends Thread{

  public void run(){

Thread.sleep(1000) //线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源

}}

开启线程:

对象.start() //启动线程,run函数运行

    public class java_thread extends Thread{

public static void main(String args[])

{

(new java_thread()).run();

System.out.println("main thread run ");

}

public synchronized  void run()

{

System.out.println("sub thread run ");

}

 

}

(2)实现Runnable接口,重写run函数

开启线程:

Thread t = new Thread(对象) //建立线程对象

t.start()

public class java_thread implements Runnable{

public static void main(String args[])

{

(new Thread(new java_thread())).start();

System.out.println("main thread run ");

}

public void run()

{

System.out.println("sub thread run ");

}

 

}

(3)实现Callable接口,重写call函数

Callable是相似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。 

import java.util.concurrent.Callable;

public class CallableWorker implements Callable{

 private int i;

 public CallableWorker(int i) throws Exception {

  this.i = i;}

 @Override

 public Integer call() throws Exception {

  System.out.println("Thread-" + Thread.currentThread().getId() + " CallableWorker test count " + i + "begin...");

  try {

   Thread.sleep(1000);

  } catch (InterruptedException e) {

   e.printStackTrace();

  }

  System.out.println("Thread-" + Thread.currentThread().getId() + " CallableWorker test count " + i + "end");

  return i+1;

 }}

Callable和Runnable有几点不一样:

①Callable规定的方法是call(),而Runnable规定的方法是run(). 

②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的

③call()方法可抛出异常,而run()方法是不能抛出异常的。 

④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.经过Future对象可了解任务执行状况,可取消任务的执行,还可获取任务执行的结果

    

6. 用户态和核心态的区别。

当一个任务(进程)执行系统调用而陷入内核代码中执行时,咱们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每一个进程都有本身的内核栈。当进程在执行用户本身的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而忽然被中断程序中断时,此时用户程序也能够象征性地称为处于进程的内核态。由于中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些相似。

用户态切换到内核态的3种方式:系统调用、异常、外围设备中断。

 

7. 用户栈和内核栈的区别。

内核栈和用户栈区别:

intel的cpu分为四个运行级别ring0~ring3,内核建立进程,建立进程的同时建立进程控制块,建立进程本身的堆栈。一个进程有两个堆栈,用户栈和系统栈。用户堆栈的空间指向用户地址空间,内核堆栈的空间指向内核地址空间。

有个CPU堆栈指针寄存器,进程运行的状态有用户态和内核态,当进程运行在用户态时。CPU堆栈指针寄存器指向的是用户堆栈地址,使用的是用户堆栈;当进程运行在内核态时,CPU堆栈指针寄存器指向的是内核堆栈地址,使用的是内核堆栈。

堆栈切换

当系统由于系统调用(软中断)或硬件中断,CPU切换到特权工做模式,进程陷入内核态,进程使用的栈也要从用户栈转向系统栈。

从用户态到内核态要两步骤,首先是将用户堆栈地址保存到内核堆栈中,而后将CPU堆栈指针寄存器指向内核堆栈。

当由内核态转向用户态,步骤首先是将内核堆栈中得用户堆栈地址恢复到CPU堆栈指针寄存器中。

内核栈和用户栈区别

1.栈是系统运行在内核态的时候使用的栈,用户栈是系统运行在用户态时候使用的栈。

当进程因为中断进入内核态时,系统会把一些用户态的数据信息保存到内核栈中,当返回到用户态时,取出内核栈中得信息恢复出来,返回到程序原来执行的地方。用户栈就是进程在用户空间时建立的栈,好比通常的函数调用,将会用到用户栈。

2.内核栈是属于操做系统空间的一块固定区域,能够用于保存中断现场、保存操做系统子程序间相互调用的参数、返回值等。用户栈是属于用户进程空间的一块区域,用户保存用户进程子程序间的相互调用的参数、返回值等。

3.每一个Windows 都有4g的进程空间,系统栈使用进程空间的地段部分,用户栈是高端部分若是用户要直接访问系统栈部分,须要有特殊的方式。

为什么要设置两个不一样的栈?

共享缘由:内核的代码和数据是为全部的进程共享的,若是不为每个进程设置对应的内核栈,那么就不能实现不一样的进程执行不一样的代码。

安全缘由:若是只有一个栈,那么用户就能够修改栈内容来突破内核安全保护。

 

8. 内存池、进程池、线程池。(c++程序员必须掌握)

自定义内存池的思想经过这个"池"字表露无疑,应用程序能够经过系统的内存分配调用预先一次性申请适当大小的内存做为一个内存池,以后应用程序本身对内存的分配和释放则能够经过这个内存池来完成。只有当内存池大小须要动态扩展时,才须要再调用系统的内存分配函数,其余时间对内存的一切操做都在应用程序的掌控之中。

应用程序自定义的内存池根据不一样的适用场景又有不一样的类型。

从线程安全的角度来分,内存池能够分为单线程内存池和多线程内存池。单线程内存池整个生命周期只被一个线程使用,于是不须要考虑互斥访问的问题;多线程内存池有可能被多个线程共享,所以则须要在每次分配和释放内存时加锁。相对而言,单线程内存池性能更高,而多线程内存池适用范围更广。

从内存池可分配内存单元大小来分,能够分为固定内存池和可变内存池。所谓固定内存池是指应用程序每次从内存池中分配出来的内存单元大小事先已经肯定,是固定不变的;而可变内存池则每次分配的内存单元大小能够按需变化,应用范围更广,而性能比固定内存池要低。

 

9. 死锁的概念,致使死锁的缘由.

死锁<DeadLock>: 是指两个或两个以上的进程在执行过程当中,因争夺资源而形成的一种互相等待的现象,若无外力做用,它们都将没法推动下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.

    主要缘由(1) 由于系统资源不足。(2) 进程运行推动的顺序不合适。(3) 资源分配不当等。

10. 致使死锁的四个必要条件。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已得到的资源保持不放。

(3) 不剥夺条件:进程已得到的资源,在末使用完以前,不能强行剥夺。

(4) 循环等待条件:若干进程之间造成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不知足,就不会发生死锁。

11. 处理死锁的四个方式。

1)忽略该问题。例如鸵鸟算法,该算法能够应用在极少发生死锁的的状况下。为何叫鸵鸟算法呢,(鸵鸟策略)

2)检测死锁而且恢复。(检测与解除策略)

3)仔细地对资源进行动态分配,以免死锁。(避免策略)

4)经过破除死锁四个必要条件之一,来防止死锁产生。(预防策略)

12. 预防死锁的方法、避免死锁的方法。

经过破除死锁四个必要条件之一,来预防死锁产生,有两种方法,一种是当其申请的资源得不到知足时,也必须放弃其原先占有的资源;另外一种方法是只适用于申请资源的进程优先级比占有该资源的进程优先级高时,若是一个进程申请的资源被其它进程占用,而申请进程的优先级较高,那么它能够强迫占有资源的进程放弃。

  仔细地对资源进行动态分配,以免死锁。

13. 进程调度算法。(周转时间 =  程序结束时间 -- 开始服务时间、带权周转时间=  周转时间 /  要求服务时间)

先来先服务(First Come First Service,FCFS)调度算法按照进程进入就绪队列的前后顺序选择能够占用处理器的进程。这是一种不可抢占方式的调度算法,优势是实现简单,缺点是后来的进程等待CPU的时间较长。它现今主要用做辅助调度法;例如结合在优先级调度算法中使用,当有两个最高优先级的进程时,则谁先来,谁就先被调度。

短执行进程优先算法(Shortest Process First,SPF)就是从就绪队列中选择一个CPU执行时间预期最短的进程,将处理器分配给它。虽然较公平,但实现难度较大,由于要准确预约下一个进程的CPU执行周期是很困难的。

•最高优先级优先(Highest Priority First,HPF)调度算法的核心是肯定进程的优先级。首先,系统或用户按某种原则为进程指定一个优先级来表示该进程所享有的调度优先权。肯定优先级的方法较多,通常可分为两类,即静态法和动态法。静态法根据进程的静态特性,在进程开始执行以前就肯定它们的优先级,一旦开始执行以后就不能改变。动态法则否则,它把进程的静态特性和动态特性结合起来肯定进程的优先级,随着进程的执行过程,其优先级不断变化。   

•进程的静态优先级肯定最基本的方法是按照进程的类型给予不一样的优先级。例如,在有些系统中,进程被划分为系统进程和用户进程。系统进程享有比用户进程高的优先级;对于用户进程来讲,则能够分为:I/O繁忙的进程、CPU繁忙的进程、I/O与CPU均衡的进程和其余进程等。

•对系统进程,也能够根据其所要完成的功能划分为不一样的类型。例如,调度进程、I/O进程、中断处理进程、存储管理进程等。这些进程还可进一步划分为不一样类型并赋予不一样的优先级。例如,在操做系统中,对于键盘中断的处理优先级和对于电源掉电中断的处理优先级是不相同的。

•基于静态优先级的调度算法实现简单,系统开销小,但因为静态优先级一旦肯定以后,直到执行结束为止始终保持不变,从而系统效率较低,调度性能不高。如今的操做系统中,若是使用优先级调度的话,则大多采用动态优先级的调度策略。

•进程的动态优先级通常能够根据如下两个方面来肯定:

• (1)根据进程占有CPU时间的长短来决定。一个进程占有处理机的时间愈长,则在被阻塞以后再次得到调度的优先级就越低。反之,其得到调度的可能性就会越大。

• (2)根据就绪进程等待CPU的时间长短来决定。一个就绪进程在就绪队列中等待的时间越长,则它得到调度选中的优先级就越高。

•因为动态优先级随时间的推移而变化,系统要常常计算各个进程的优先级,所以,系统要为此付出必定的开销。

•最高优先级优先调度算法用于多道批处理系统中较好,但它使得优先级较低的进程等待时间较长,这对于分时系统中要想得到较好的响应时间是不容许的,因此在分时系统中多采用时间片轮转法来进行进程调度。

 时间片轮转(Round Robin,RR)法的基本思路是让每一个进程在就绪队列中的等待时间与享受服务的时间成比例。在时间片轮转法中,须要将CPU的处理时间分红固定大小的时间片,例如,几十毫秒至几百毫秒。若是一个进程在被调度选中以后用完了系统规定的时间片,但又未完成要求的任务,则它自行释放本身所占有的CPU而排到就绪队列的末尾,等待下一次调度。同时,进程调度程序又去调度当前就绪队列中的第一个进程。

•显然,轮转法只能用来调度分配一些能够抢占的资源。这些能够抢占的资源能够随时被剥夺,并且能够将它们再分配给别的进程。CPU是可抢占资源的一种。但打印机等资源是不可抢占的。因为做业调度是对除了CPU以外的全部系统硬件资源的分配,其中包含有不可抢占资源,因此做业调度不使用轮转法。在轮转法中,时间片长度的选取很是重要。首先,时间片长度的选择会直接影响到系统的开销和响应时间。若是时间片长度太短,则调度程序抢占处理机的次数增多。这将使进程上下文切换次数也大大增长,从而加剧系统开销。反过来,若是时间片长度选择过长,例如,一个时间片能保证就绪队列中所需执行时间最长的进程能执行完毕,则轮转法变成了先来先服务法。时间片长度的选择是根据系统对响应时间的要求和就绪队列中所容许最大的进程数来肯定的。

• 在轮转法中,加入到就绪队列的进程有3种状况,一种是分给它的时间片用完,但进程还未完成,回到就绪队列的末尾等待下次调度去继续执行。另外一种状况是分给该进程的时间片并未用完,只是由于请求I/O或因为进程的互斥与同步关系而被阻塞。当阻塞解除以后再回到就绪队列。第三种状况就是新建立进程进入就绪队列。若是对这些进程区别对待,给予不一样的优先级和时间片,从直观上看,能够进一步改善系统服务质量和效率。例如,咱们可把就绪队列按照进程到达就绪队列的类型和进程被阻塞时的阻塞缘由分红不一样的就绪队列,每一个队列按FCFS原则排列,各队列之间的进程享有不一样的优先级,但同一队列内优先级相同。这样,当一个进程在执行完它的时间片以后,或从睡眠中被唤醒以及被建立以后,将进入不一样的就绪队列。

 

14. Windows内存管理的方式(块式、页式、段式、段页式).

内存管理是操做系统中的重要部分,两三句话恐怕谁也说不清楚吧~~我先说个大概,但愿可以抛砖引玉吧 当程序运行时须要从内存中读出这段程序的代码。代码的位置必须在物理内存中才能被运行,因为如今的操做系统中有很是多的程序运行着,内存中不可以彻底放下,因此引出了虚拟内存的概念。把哪些不经常使用的程序片段就放入虚拟内存,当须要用到它的时候在load入主存(物理内存)中。这个就是内存管理所要作的事。内存管理还有另一件事须要作:计算程序片断在主存中的物理位置,以便CPU调度。 内存管理有块式管理,页式管理,段式和段页式管理。如今经常使用段页式管理。

 块式管理:把主存分为一大块、一大块的,当所需的程序片段不在主存时就分配一块主存空间,把程序片段load入主存,就算所需的程序片度只有几个字节也只能把这一块分配给它。这样会形成很大的浪费,平均浪费了50%的内存空间,可是易于管理。

页式管理:把主存分为一页一页的,每一页的空间要比一块一块的空间小不少,显然这种方法的空间利用率要比块式管理高不少。

 段式管理:把主存分为一段一段的,每一段的空间又要比一页一页的空间小不少,这种方法在空间利用率上又比页式管理高不少,可是也有另一个缺点。一个程序片段可能会被分为几十段,这样不少时间就会被浪费在计算每一段的物理地址上(计算机最耗时间的你们都知道是I/O吧)。

段页式管理:结合了段式管理和页式管理的优势。把主存分为若干页,每一页又分为若干段。

二维逻辑地址:段号+段内地址
分页与分段的主要区别:
1)、段是信息的逻辑单位,它是根据用户的须要划分的,所以段对用户是可见的;页是信息的物理单位,是为了管理主存的方便而划分的,对用户是透明的。
2)、页的大小固定不变,由系统决定。段的大小是不固定的,它由其完成的功能决定。
3)、段式向用户提供的是二维地址空间,页式向用户提供的是一维地址空间,其页号和页内偏移是机器硬件的功能。
4)、因为段是信息的逻辑单位,所以便于存贮保护和信息的共享,页的保护和共享受到限制。

分页与分段存储管理系统虽然在不少地方类似,但从概念上讲,二者是彻底不一样的,它们之间的区别以下:
  ①页是信息的物理单位。分页的目的是实现离散分配,减小外部碎片,提升内存利用率。段是信息的逻辑单位。每一段在逻辑上是一组相对完整的信息集合。
  ②分页式存储管理的做业地址空间是一维的,而分段式存储管理的做业地址空间是二维的。
  ③页的大小固定且由系统肯定,是等长的。而段的长度不定。
  ④分页的优势体如今内存空间的管理上,而分段的优势体如今地址空间的管理上。

 

15. 内存连续分配方式采用的几种算法及各自优劣。

1) 单一连续分配  是一种最简单的存储管理方式,其优势是软件处理简单,最大缺点是存储器不能充分利用。多用于单用户微机操做系统中。
2) 动态分区分配  是多道程序环境下各类存储管理方式中最简单的一种。它将内存划分红若干个分区,在每一个分区中按照连续分配方式分配给一个做业。分区形式: a) 固定分区分配:指内存在处理做业前已被划分红若干个大小不等的分区,存储管理程序根据每一个做业步的最大存储量分配一个足够大的分区给它。当找不到一个足够大的分区时,则通知做业调度挑选另外一做业,这种方式分配和回收内存简单,但内存利用不充分,会产生“碎片”空间。b) 可变分区分配:指内存事先并未被分区,只有看成业进入内存时,才根据做业的大小创建分区。其特色是分区的个数和大小都是可变的,但须要创建分配区表和空白区表,且表的长度是不固定的。
3) 可重定位分区分配  为使各分区中的用户程序能移到内存的一端,使碎片集中于另外一端成为一个大分区,在程序执行过程当中,需对做业移动过程当中的与地址有关项进行调整。这种分配方法的优势是清除碎片,更大程度地利用内存空间,但必须硬件的支持,且要花费时间。

 

16. 动态连接及静态连接.

静态连接库与动态连接库都是共享代码的方式,若是采用静态连接库,则不管你愿不肯意,lib 中的指令都所有被直接包含在最终生成的 EXE 文件中了。可是若使用 DLL,该 DLL 没必要被包含在最终 EXE 文件中,EXE 文件执行时能够“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态连接库和动态连接库的另一个区别在于静态连接库中不能再包含其余的动态连接库或者静态库,而在动态连接库中还能够再包含其余的动态或静态连接 库

     动态连接是指在生成可执行文件时不将全部程序用到的函数连接到一个文件,由于有许多函数在操做系统带的dll文件中,当程序运行时直接从操做系统中找。   

     而静态连接就是把全部用到的函数所有连接到exe文件中。

    动态连接是只创建一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入;   

     而静态连接是把全部的代码和数据都复制到本模块中,运行时就再也不须要库了。

17. 基本分页、请求分页储存管理方式。18. 基本分段、请求分段储存管理方式。

分页式存储管理的基本原理:采用分页存储器容许把一个做业存放到若干不相邻的分区中,既可免去移动信息的工做,又可尽可能减小主存的碎片。分页式存储管理的基本原理以下: 

一、 页框:物理地址分红大小相等的许多区,每一个区称为一块; 

二、址分红大小相等的区,区的大小与块的大小相等,每一个称一个页面。 

三、 逻辑地址形式:与此对应,分页存储器的逻辑地址由两部分组成,页号和单元号。逻辑地址格式为 

页号 单元号(页内地址) 

采用分页式存储管理时,逻辑地址是连续的。因此,用户在编制程序时仍只须使用顺序的地址,而没必要考虑如何去分页。 

四、页表和地址转换:如何保证程序正确执行呢?采用的办法是动态重定位技术,让程序的指令执行时做地址变换,因为程序段以页为单位,因此,咱们给每一个页设立一个重定位寄存器,这些重定位寄存器的集合便称页表。页表是操做系统为每一个用户做业创建的,用来记录程序页面和主存对应页框的对照表,页表中的每一栏指明了程序中的一个页面和分得的页框的对应关系。绝对地址=块号*块长+单元号 

以上从拓扑结构角度分析了对称式与非对称式虚拟存储方案的异同,实际从虚拟化存储的实现原理来说也有两种方式;即数据块虚拟与虚拟文件系统. 

数据块虚拟存储方案着重解决数据传输过程当中的冲突和延时问题.在多交换机组成的大型Fabric结构的SAN中,因为多台主机经过多个交换机端口访问存储设备,延时和数据块冲突问题很是严重.数据块虚拟存储方案利用虚拟的多端口并行技术,为多台客户机提供了极高的带宽,最大限度上减小了延时与冲突的发生,在实际应用中,数据块虚拟存储方案以对称式拓扑结构为表现形式. 

虚拟文件系统存储方案着重解决大规模网络中文件共享的安全机制问题.经过对不一样的站点指定不一样的访问权限,保证网络文件的安全.在实际应用中,虚拟文件系统存储方案以非对称式拓扑结构为表现形式. 

虚拟存储技术,其实是虚拟存储技术的一个方面,特指以CPU时间和外存空间换取昂贵内存空间的操做系统中的资源转换技术 

基本思想:程序,数据,堆栈的大小能够超过内存的大小,操做系统把程序当前使用的部分保留在内存,而把其余部分保存在磁盘上,并在须要时在内存和磁盘之间动态交换,虚拟存储器支持多道程序设计技术 

目的:提升内存利用率 

管理方式 

A 请求式分页存储管理 

在进程开始运行以前,不是装入所有页面,而是装入一个或零个页面,以后根据进程运行的须要,动态装入其余页面;当内存空间已满,而又须要装入新的页面时,则根据某种算法淘汰某个页面,以便装入新的页面 

B 请求式分段存储管理 

为了能实现虚拟存储,段式逻辑地址空间中的程序段在运行时并不所有装入内存,而是如同请求式分页存储管理,首先调入一个或若干个程序段运行,在运行过程当中调用到哪段时,就根据该段长度在内存分配一个连续的分区给它使用.若内存中没有足够大的空闲分区,则考虑进行段的紧凑或将某段或某些段淘汰出去,这种存储管理技术称为请求式分段存储管理

 

19. 分段分页方式的比较各自优缺点。

页和分段系统有许多类似之处,但在概念上二者彻底不一样,主要表如今:

一、页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提升内存的利用率;或者说,分页仅仅是因为系统管理的须要,而不是用户的须要。

段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的知足用户的须要。

二、页的大小固定且由系统肯定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,于是一个系统只能有一种大小的页面。

段的长度却不固定,决定于用户所编写的程序,一般由编辑程序在对源程序进行编辑时,根据信息的性质来划分。

 

三、分页的做业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符,便可表示一地址。

分段的做业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

20. 几种页面置换算法,会算所需换页数。(LRU用程序如何实现?)

 地址映射过程当中,若在页面中发现所要访问的页面再也不内存中,则产生缺页中断。当发生缺页中断时操做系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。而用来选择淘汰哪一页的规则叫作页面置换算法。常见的置换算法有:

1)最佳置换算法(OPT)(理想置换算法)

这是一种理想状况下的页面置换算法,但其实是不可能实现的。该算法的基本思想是:发生缺页时,有些页面在内存中,其中有一页将很快被访问(也包含紧接着的下一条指令的那页),而其余页面则可能要到十、100或者1000条指令后才会被访问,每一个页面均可以用在该页面首次被访问前所要执行的指令数进行标记。最佳页面置换算法只是简单地规定:标记最大的页应该被置换。这个算法惟一的一个问题就是它没法实现。当缺页发生时,操做系统没法知道各个页面下一次是在何时被访问。虽然这个算法不可能实现,可是最佳页面置换算法能够用于对可实现算法的性能进行衡量比较。

2)先进先出置换算法(FIFO)

最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,老是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最先调入内存的页,其再也不被使用的可能性比刚调入内存的可能性大。创建一个FIFO队列,收容全部在内存中的页。被置换页面老是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。

这种算法只是在按线性顺序访问地址空间时才是理想的,不然效率不高。由于那些常被访问的页,每每在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。

FIFO的另外一个缺点是,它有一种异常现象,即在增长存储块的状况下,反而使缺页中断率增长了。固然,致使这种异常现象的页面走向其实是不多见的。

3)最近最久未使用(LRU)算法

FIFO算法和OPT算法之间的主要差异是,FIFO算法利用页面进入内存后的时间长短做为置换依据,而OPT算法的依据是未来使用页面的时间。若是以最近的过去做为不久未来的近似,那么就能够把过去最长一段时间里未曾被使用的页面置换掉。它的实质是,当须要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。这种算法就称为最久未使用算法(Least Recently Used,LRU)。

LRU算法是与每一个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。

LRU算法是常常采用的页面置换算法,并被认为是至关好的,可是存在如何实现它的问题。LRU算法须要实际硬件的支持。其问题是怎么肯定最后使用时间的顺序,对此有两种可行的办法:

    1.计数器。最简单的状况是使每一个页表项对应一个使用时间字段,并给CPU增长一个逻辑时钟或计数器。每次存储访问,该时钟都加1。每当访问一个页面时,时钟寄存器的内容就被复制到相应页表项的使用时间字段中。这样咱们就能够始终保留着每一个页面最后访问的“时间”。在置换页面时,选择该时间值最小的页面。这样作,不只要查页表,并且当页表改变时(因CPU调度)要维护这个页表中的时间,还要考虑到时钟值溢出的问题。

    2.栈。用一个栈保留页号。每当访问一个页面时,就把它从栈中取出放在栈顶上。这样一来,栈顶老是放有目前使用最多的页,而栈底放着目前最少使用的页。因为要从栈的中间移走一项,因此要用具备头尾指针的双向链连起来。在最坏的状况下,移走一页并把它放在栈顶上须要改动6个指针。每次修改都要有开销,但须要置换哪一个页面却可直接获得,用不着查找,由于尾指针指向栈底,其中有被置换页。

因实现LRU算法必须有大量硬件支持,还须要必定的软件开销。因此实际实现的都是一种简单有效的LRU近似算法。

一种LRU近似算法是最近未使用算法(Not Recently Used,NUR)。它在存储分块表的每一表项中增长一个引用位,操做系统按期地将它们置为0。当某一页被访问时,由硬件将该位置1。过一段时间后,经过检查这些位能够肯定哪些页使用过,哪些页自上次置0后还未使用过。就可把该位是0的页淘汰出去,由于在最近一段时间里它未被访问过。

4)Clock置换算法(LRU算法的近似实现)

5)最少使用(LFU)置换算法

在采用最少使用置换算法时,应为在内存中的每一个页面设置一个移位寄存器,用来记录该页面被访问的频率。该置换算法选择在最近时期使用最少的页面做为淘汰页。因为存储器具备较高的访问速度,例如100 ns,在1 ms时间内可能对某页面连续访问成千上万次,所以,一般不能直接利用计数器来记录某页被访问的次数,而是采用移位寄存器方式。每次访问某页时,便将该移位寄存器的最高位置1,再每隔必定时间(例如100 ns)右移一次。这样,在最近一段时间使用最少的页面将是∑Ri最小的页。

LFU置换算法的页面访问图与LRU置换算法的访问图彻底相同;或者说,利用这样一套硬件既可实现LRU算法,又可实现LFU算法。应该指出,LFU算法并不能真正反映出页面的使用状况,由于在每一时间间隔内,只是用寄存器的一位来记录页的使用状况,所以,访问一次和访问10 000次是等效的。

21. 虚拟内存的定义及实现方式。

 虚拟内存,它的做用与物理内存基本类似,但它是做为物理内存的“后备力量”而存在的,也就是说,只有在物理内存已经不够使用的时候,它才会发挥做用。

  改变页面文件位置的方法是:用鼠标右键点击“个人电脑”,选择“属性→高级→性能设置→高级→更改虚拟内存”,在驱动器栏里选择想要改变到的位置

22. 操做系统的四个特性。

  并发性(concurrency):指在计算机系统中存在着许多并发执行的活动。对计算机系统 而言,并发是指宏观上看系统内有多道程序同时运行,微观上看是串行运行。由于在 大多数计算机系统中通常只有一个CPU,在任意时刻只能有一道程序占用CPU。

  共享性(sharing):系统中各个并发活动要共享计算机系统中的各类软、硬件资源,所以操做系统必须解决在多道程序间合理地分配和使用资源问题。 

  虚拟性(virtual):虚拟是操做系统中的重要特征,所谓虚拟是指把物理上的一台设备 变成逻辑上的多台设备。例如,在操做系统中采用了spooling技术,能够利用快速、 大容量可共享的磁盘做为中介,模拟多个非共享的低速的输入输出设备,这样的设备 称为虚拟设备。 

  异步性:在多道程序环境下容许多个进程并发执行,但只有进程在得到所需的资源后方能执行。在单处理机环境下,因为系统中只有一台处理机,于是每次只容许一个进程执行,其他进程只能等待。

23. DMA。

直接内存存取(Direct Memory Access) 改善系统实时效能的一个熟知的方法是,额外提供一个逻辑模块,在事件发生时产生响应,并容许处理器在较方便的时间来处理信息。这个DMA控制器一般将传送到模块的信息复制到内存(RAM),并容许已处理的信息自动从内存移到外部外围装置。全部这些工做皆独立于目前的CPU活动-详见图1。

 

这种方式确定有所助益,但其效益仅限于延迟必然发生的事件-CPU仍是得在某一时间处理信息。S12X采用一个根本的方法,即提供「智能型DMA」控制器,不仅移动资料,同时直接执行全部的处理工做。

24. Spooling。

 脱机输入和脱机输出
在多道环境下,能够用OS的一道管理程序实现从I/O设备输入数据并存放到磁盘上,模拟脱机输入;用OS的另外一道管理程序将磁盘上的数据输出到I/O设备上,模拟脱机输出;这种假脱机I/O操做称为Spooling技术。

Spooling是一种虚拟设备技术、一种资源转换技术。

25. 外存分配的几种方式,及各类优劣。

连续分配:为每个文件分配一组相邻接的盘块;物理上造成了顺序文件结构;外存上会出现“ 碎片” ,用“ 紧凑” 的方法解决。优缺点:顺序(批量)访问容易、速度快;要求有连续的存储空间(有时须要做紧凑处理)、必须事先知道文件的长度。

连接分配:离散分配方式。优缺点:消除了“碎片”,有利于文件的增/删/改。隐式连接

在文件的每一个目录项中,都含有指向连接文件第一盘块和最后一个盘块的指针,只适合于顺序访;显式连接,把用于连接文件各物理块的指针,显式地存放在内存的一张“连接表”中。

索引分配:单级索引分配每一个文件一个索引块(表);多级索引分配当文件较大,须要不少个索引块时,能够为各索引块创建一个索引表(块);混合索引分配方式。

相关文章
相关标签/搜索