操作系统 琐碎知识点整理

第01章 操作系统引论

  • 操作系统(Operating System):主要作用是管理好这些设备、提高它们的利用率和系统吞吐量、为用户和应用程序提供一个简单的接口。
  • 操作系统主要目标:方便性、有效性、可扩充性、开放性。
  • 系统资源可分为:处理机(分配和控制)、存储器(分配和回收)、I/O设备(分配、回收、操纵)、文件(存取、共享、保护)。
  • 硬实时和软实时:硬实时必须满足任务对截止时间的要求,否则可能出现难以预测的后果;软实时也有截止时间,但不太严格,偶尔错过了对系统产生的影响也不会太大。
  • 操作系统的基本特性:并发(concurrence)、共享(sharing)、虚拟(virtual)、异步(asynchronism)。
  • 并行和并发
    并行:两个或多个事件在同一时刻发生
    并发:两个或多个事件在同一时间间隔发生(在一段时间间隔中,宏观上有多个程序在同时运行,但微观上程序是分时交替执行的)
  • 进程:系统中能独立运行并作为资源分配的基本单位。
  • 共享:系统中的资源可以供内存中多个并发执行的进程共同使用。
  • 互斥共享方式、同时访问方式
    互斥共享:虽然可以提供给多个进程(线程)使用,但在一段时间内,只允许一个进程访问该资源(例如打印机、磁带机等)
    同时访问:可以在宏观上“同时”访问的资源(例如磁盘)
  • 虚拟:把一个物理实体变成若干个逻辑上对应物的功能。有:时分复用、空分复用。
  • 一个进程在提出某种资源要求后,发现现在有其他进程占用该进程,需要等待,并且释放处理机。等该资源空闲、并再次得到处理机时,方可继续执行。
  • 各程序的性能不同,有的侧重计算而少IO,有的计算少而IO多。所以可能存在先进入内存的作业后完成,而后进入先完成。也就是说进程是以人们不可预知的速度向前推进的,叫做进程的异步性
  • 操作系统主要功能:处理机管理、存储器管理、设备管理、文件管理
    处理机管理:进程控制、进程同步、进程通信、调度
    存储器管理:内存分配、内存保护、地址映射、内存扩充
    设备管理:缓冲管理、设备分配、设备处理
    文件管理:文件存储空间管理、目录管理、文件的读写管理和保护

第02章 进程的描述与控制

  • 操作系统中有专门一个数据结构,叫进程控制块(Process Control Block,PCB):利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。
  • 进程特征:动态性、并发性、独立性、异步性。
  • 进程的三种基本状态:
    就绪态(Ready):已经分配到除CPU外的所以必要资源,得到CPU就可以立即执行
    执行态(Running):已获得CPU,在执行的状态
    阻塞态(Block):由于发生某事件(申请IO、缓冲区失败等),暂时无法继续执行的状态。

  • 创建状态、终止状态
    创建状态:一般创建进程需要通过多个步骤才能完成:①申请一个空白PCB ②向PCB中写控制和管理进程的信息 ③为其分配必须的资源 ④把进程转入就绪状态,并插入就绪队列中(例如资源不足、队列满了都可能导致暂时停留在这一状态)
    终止状态:终止也要通过两个步骤:①等待操作系统进行善后处理 ②将PCB清零,归还给系统

  • 挂起操作(和挂起对应的是激活操作)
    挂起的原因:终端用户的需要、父进程的请求、负荷调节的需要、操作系统的需要。
    活动就绪→静止就绪
    活动阻塞→静止阻塞
    静止就绪→活动就绪
    静止阻塞→活动阻塞

  • 进程控制一般是由OS内核中的原语来实现的。原语:原子操作,要么全做要么全不做。
  • OS内核:与硬件紧密相关的模块、各种常用设备的驱动、运行频率较高的模块,安排在内核中、常驻内存。
  • 为防止OS本身受到应用程序有意、无意的破坏,将处理机的执行状态分为两种状态:系统态、用户态。
    系统态(管态、内核态):具有较高的特权,能执行一切命令,访问所有寄存器和存储区。
    用户态(目态):具有较低的权限,仅能执行指定的命令,访问指定的寄存器和存储区。
  • 进程同步:对多个相关进程在执行次序上进行协调,使并发执行的进程之间按照一定的规则(或时序)共享系统资源,并且能很好地相互合作。
  • 进程同步机制:硬件同步、信号量、管程等。
  • 进入区:进入临界区前,对临界资源进行检查,看是否正被访问的代码。
    临界区:每个进程中访问临界资源的那段代码。
    退出区:将临界区正被访问的标志,恢复为未被访问。
    剩余区:除了上面几部分,其他都叫剩余区代码
  • 同步机制应遵循原则:
    空闲让进:如果临界资源处于空闲状态,应让进程进入临界区
    忙则等待:如果已有进程进入自己的临界区,其他进程必须等待
    有限等待:应该保证请求访问临界资源的进程,在有限时间内能进入自己的临界区,以免进入“死等”状态
    让权等待:当进程无法进入临界区时,应该释放自己的处理机,以免进入“忙等”状态
  • 硬件同步机制:可以将标志看成一个锁,“锁开”进入,“锁闭”等待。每个进入临界区的进程,要进行锁测试;关了则要等待,开着必须马上关上,然后进入临界区。为防止多个进程同时测试到所为开,测试和关锁操作必须连续的,为此有下面的方式:
    ①关中断:进入锁测试前关闭中断,测试和关锁后再打开中断。
    ②利用Test-and-Set指令实现互斥:这是一个原语操作。lock=FALSE时,资源空闲;lock=TRUE时,资源占用。lock初始值为FALSE,进入临界区前,TS指令会测试lock。FALSE时,赋TRUE给lock;TRUE时,循环测试。
    bool TS(bool* lock){
        bool old;
        old=*lock;
        *lock=TRUE;
        return old;
    }
    
    do{
        while TS(&lock);    //不断坚持lock,直到其为FALSE为止
        //临界区代码
        lock:=FALSE;
        //剩余区代码
    }while(TRUE)
    ③利用Swap指令实现进程互斥
    do{
        key=TRUE;
        do{
            swap(&lock,&key);
        }while(key!=FALSE);
        //临界区
        lock=FALSE;
        //剩余区
    }while(TRUE);
  • 信号量机制
    整型信号量:主要通过wait(S)和signal(S)来访问。这是两个原子操作,执行过程中不可中断。
    wait(S){
        while(S<=0);
        S--;
    }
    
    signal(S){
        S++;
    }
    记录型信号量:整型信号未遵循“让权等待”原则,会处于“忙等”状态。当value小于0的时候,用block原语进行自我阻塞。放弃处理机,并插入到信号量链表S->list中。signal的时候,当value+1后还小于等于0,表明在信号量链表中还有等待的进程,可以用wakeup原语唤醒一个。
    如果S->value的初始值为1,表明只允许一个进程访问资源。
    typedef struct{
        int value;
        struct process_control_block *list;
    }semaphore;
    
    wait(semaphore *S){
        S->value--;
        if(S->value<0)
            block(S->list);
    }
    
    signal(semaphore *S){
        S->value++;
        if(S->value<=0)
            wakeup(S->list);
    }
    AND型信号量:上面的都只是仅共享一个临界资源,如果一个进程需要两个或者更多的共享资源,采用上面的方式很可能造成死锁。AND同步机制的基本思想是:将进程整个运行过程中所需资源,一次性分配给它,进程结束后再一起释放。只有一个资源未能分配,其他可能分配的也不给它。
    Swait(S1,S2,...Sn){
        while(TRUE){
            if(Si>=1&&...&&Sn>=1){
                for(i=1;i<=n;i++)
                    Si--;
                break;
            }
            else{
                //进程进入等待队列
            }
        }
    
    }
    
    Ssignal(S1,S2,...Sn){
        while(TRUE){
            for(i=1;i<=n;i++)
                Si++;
            //将等待队列中的进程放入就绪队列
        }
    }
    信号量集:上面的每次只对某类临界资源进行一个单位的申请和释放。如果一次需要N个的话,这种操作比较低效,甚至增加死锁概率。此外,某些状况下,当所申请的资源数目少于某一下限时,不予分配。所以信号量集是基于这两点,对AND信号量机制的扩充。先测试该资源下限值ti,Si>=ti才进行分配;允许分配时候,Si:=Si-di。di是进程对该资源的需求值。
  • PV原语操作(即前面的wait和signal):
    P原语操作的动作是:

    ①sem减1;②若sem减1后仍大于或等于零,则进程继续执行;③若sem减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
    V原语操作的动作是:
    ①sem加1;②若相加结果大于零,则进程继续执行;③若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
    PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
     
  • 管程机制:用少量的信息和对该资源所执行的操作来表征该资源,忽略它们内部结构和实现细节。包含了一种面向对象的思想。
    管程由4部分组成:①管程的名称 ②局部于管程的共享数据结构说明 ③对该数据结构进行操作的一组过程 ④对局部于管程的共享数据结构设置初始值的语句。
  • 进程通信:共享存储器系统、管道通信系统、消息传递系统、客户机-服务器系统
    前面进程间的 互斥与同步 也算进程通信,但一般归为低级进程通信。而上面四种是高级进程通信
  • 共享存储器系统(Shared-Memory System)
    基于共享数据结构的通信方式:要求各进程公用某些数据结构,操作系统仅提供共享存储器,程序员负责对公用数据结构的设置和进程间同步处理(适用于少量数据)
    基于共享存储区的通信方式:可以传输大量数据,在内存中划出一块共享存储区域。各个进程可以通过对该区域的读或写交换信息。
  • 管道(pipe)通信系统:用于连接一个读进程和一个写进程,实现它们之间通信的一个共享文件,又名pipe文件。
    管道机制提供以下三方面的协调能力:①互斥 ②同步 ③确定对方是否存在
  • 消息传递系统(Message passing system):以格式化的消息为单位,将通信的消息封装在消息中,利用操作系统提供的一组通信命令(原语),进行传递。
    直接通信方式:发送进程利用OS所提供的原语,直接把消息发给目标进程。
    简介通信方式:通过共享中间实体(称为邮箱)的方式进行消息的发送和接收。
  • 客户机-服务器系统(Client-Server system):
    主要实现方法:套接字(Socket)、远程过程调用、远程方法调用
  • 进程是分配资源的基本单位;线程是系统调度和分派的基本单位。
  • 属于同一进程的所有线程都具有相同的地址空间。

第03章 处理机调度与死锁

  • 高级调度(High Level Scheduling):作业调度。决定将外存上处于后备队列中的哪几个作业调入内存,并创建进程、分配资源、放入就绪队列。
    低级调度(Low Level Scheduling):进程调度、短程调度。决定就绪队列中哪个进程获得处理机。
    中级调度(Intermediate Scheduling):内存调度。提高内存利用率和系统吞吐量。实际上就是第4章的对换功能。
  • 作业调度算法:先来先服务(FCFS)、短作业优先(SJF)、优先级调度(PSA)、高响应比优先调度(HRRN)
    先来先服务算法(first-come first-serve):优先考虑在系统中等待时间最长的作业。该算法在单处理机系统中已很少作为主调度算法,但可以与其他算法结合形成一种更有效的方法。例如按照进程优先级设置多个队列,每一个队列都基于FCFS算法。
    短作业优先算法(short job first):实际情况中,这种算法占较大比例。这种算法必须预知作业时间。该算法完全忽视作业等待时间,可能出现饥饿现象。
    优先级调度算法(priority-scheduling algorithm):在优先级调度算法中,基于作业的紧迫程度进行调度的。由外部赋予作业相应的优先级。
    高响应比优先调度算法(Highest Response Ratio Next):该算法综合了FCFS和SJF,既考虑作业的等待时间,又考虑作业的运行时间。它的调度优先级是:优先级=(等待时间+要求服务时间)/要求服务时间。这种算法下:①等待时间相同,要求服务时间越短优先级越高,等同于SJF算法 ②要求服务时间相同,等同于FCFS算法 ③长作业的优先级,也会随着等待时间的增加而提高。
  • 可抢占和不可抢占资源
    可抢占性资源:某进程获得该资源后,资源还可以被其他进程抢占。这类资源不会引起死锁。
    不可抢占性资源:一旦系统把资源分配给该进程后,就不能强行收回,需要等进程用完后自行释放。可能会引起死锁。
  • 死锁(deadlock):如果一组进程中每一个进程都在等待仅由该组进程中的其他进程才能引发的事件,那么该组进程是死锁的。
  • 死锁产生的必要条件:互斥、请求和保持、不可抢占、循环等待
    互斥条件:一段时间内,资源只能被一个进程占用。
    请求和保持条件:进程已经保持了至少一个资源,又提出新的资源请求。
    不可抢占条件:进程已获得资源在未使用完之前不能被抢占,只能由进程自己释放。
    循环等待条件:必然存在一个进程-资源的循环链,例如:P0等待P1占用的资源;P1等待P2占用的资源;......Pn等待P0占用的资源。
  • 预防死锁:破坏产生死锁4个必要条件中的一个或多个。
  • 避免死锁:不是破坏条件,而是分配过程中,防止系统进入不安全状态。例如银行家算法。

第04章 存储器管理

  • 程序运行步骤:编译→连接→装入
    编译:由编译器对用户源程序进行编译,形成若干个目标模块。
    链接:由链接器将编译后形成的一组目标模块,和他们所需的库函数链接在一起,形成一个完整的装入模块。
    装入:由装入程序将模块装入内存。
  • 程序装入的方式:绝对装入、可重定位装入、动态运行时的装入
    绝对转入方式:用户程序经编译后,产生的是绝对地址(即物理地址)的目标代码。程序中的相对地址(逻辑地址)和实际内存地址完全相同。
    可重定位装入方式:装入模块中的所有逻辑地址和实际装入内存后的物理地址不同,装入后需要通过一定计算得到实际物理地址,并且对程装入模块进行修改。
    动态运行时装入方式:可以装入到内存任何允许位置,运行时不允许在内存中移动位置。但模块装入内存后,不马上把逻辑地址转为物理地址,而是在程序真正执行时候才进行。
  • 连续分配方式有这么4类:单一连续分配、固定分区分配、动态分区分配、动态可重定位分区分配

    单一连续分配:单道程序环境下,内存分为系统区和用户区。用户区仅有一道用户程序。
    固定分区分配:为了可以装入多道程序、并且之间互不干扰。把用户空间划分为若干个固定大小的区域。每个分区只装入一道作业。
    动态分区分配:根据进程实际需要,动态为之分配内存空间。

    基于顺序搜索的动态分区分配算法:通常将系统中的空闲分区链接为一个链。依次搜索找到一个大小满足要求的分区。适用于不太大的系统。
    1). 首次适应算法(first fit):要求链以地址递增的次序链接。找到一个大小满足的空闲分区,划出一部分空间,余下的仍留在链中。(优先利用低址的空闲部分,地址会不断被划分,剩下许多难以利用的小分区)
    2). 循环首次适应算法(next fit):每次从上次找到空闲分区的下一个空闲分区开始查找。(低址部分不会留下很小的空闲分区,但会缺乏很大的空闲分区)
    3). 最佳适应算法(best fit):会把满足要求、又是最小的空闲分区分配给作业。(似乎是最佳的,但每次分配后切割下来的空闲分区总是最小的,会留下很多碎片)
    4). 最坏适应算法(worst fit):总是挑选一个最大的空闲分区。

    基于索引搜索的动态分区分配算法:大、中型系统适用
    1).快速适应算法(quick fit):又称分类搜索法。按照容量大小分类,每一类同样容量的空闲分区用一个独立的空闲分区链表。同时有一张管理索引表,指向各不同大小的空闲分区链表的头指针。
    2).伙伴系统(buddy system):系统开始时,整个内存区是大小为2^m的空闲分区,运行中再不断划分。按照大小的相同,划分出多个空闲分区的双向链表。
    当需要分配一个长度为n的空间时,先计算i满足:2^(i-1)<n<=2^i。然后在2^i中查找空闲分区,找不到再去2^(i+1)中查找。如果找到了,把2^(i+1)分割为2个2^i。以此类推。
    3).哈希算法:利用哈希查找,建立哈希表。

    动态可重定位分区分配:在系统中增设一个寄存器,用来存放程序在内存中的起始地址,这样每次执行“紧凑”操作后就不用再一个个去改地址。(紧凑操作:运行一段时间后,把程序整理得经凑,留出后面大片的空闲空间,防止碎片化)
  • 对换(swapping)
    为什么需要对换?
    ①内存中某些进程由于阻塞,并没有在运行,却占用了大量空间。
    ②有许多作业,因为内存空间不够,在外存上驻留,进不了内存运行。
    有什么对换类型?
    ①整体对换:以进程为单位,进行对换,也就是前面提到的中级调度
    ②页面(分段)对换:以进程一个“页面”或一个“分段”为单位进行的,又称为“部分对换”。
    为实现对换,需要系统实现那些功能?
    对对换空间的管理、进程的换出、进程的换入
  • 离散分配:如果允许将一个进程直接分散地装入到许多不相邻的分区中,可以充分利用空间,也不用去执行开销较大的“紧凑”操作。因此产生了离散分配方式。
    离散分配有以下三种:分页存储管理方式、分段存储管理方式、段页式存储管理方式
    分页存储管理方式:将用户程序的地址空间分为若干个固定大小的区域,称为“页”或“页面”。典型页面大小为1KB。
    分段存储管理方式:把用户程序的地址空间分为若干个大小不同的段,每一段可定义一组相对完整的信息。
    段页式存储管理方式:结合分页和分段两者的优点,目前应用较广泛的一种存储管理方式
  • 分页存储
    当进程要访问某个逻辑地址中的数据时,分页地址变换机构会自动将相对地址分为分页号页内地址两个部分,再以页号为索引去检索页表。
  • 分段存储
    引入分段存储管理的原因:方便编程、信息共享、信息保护、动态增长、动态链接。
  • 联想存储器:联想存储器在计算机系统中是用于地址变换的。不按地址而按给定内容的特征进行存取的存储器。
    联想存储器的特点是:①除有存储功能外,还具有信息处理功能。它能根据送来内容的特征查找存储单元。②对各个存储单元并行进行查找,因而能显著提高查找速度。这些特点与人脑的“联想”功能有所相似,因而被称为联想存储器。

第05章 虚拟存储器

  • 前面描述的各种存储器管理方式,都需要将整个作业全部装入内存后才能运行。但:①有的作业很大:内存根本不够用,运行不了。 ②有大量作业要求运行:只能让小部分运行,多数在外存等待。
  • 局部性原理:
    ①程序执行时,除了少部分转移和过程调用指令外,多数情况是顺序执行的
    ②过程调用将会使程序执行轨迹从一部分区域转移到另一部分区域
    ③程序中存在许多循环结构,由少数指令构成,但将被执行多次
    ④程序中包括许多对数据结构的处理,这些处理往往局限在很小的范围内
  • 程序局限性的表现:
    时间局限性:如果某条指令被执行,那么不久后它可能会被再次执行。数据也是如此。
    空间局限性:如果一个存储单元被访问,那么不久后临近的存储单元也可能被访问。
  • 基于上面几点,虚拟存储是:应用程序在运行前没有必要全部装入内存,而仅须将那些当前要运行的少数页面和段装入,其余部分暂留在盘上。
  • 虚拟存储器的特征:多次性(装入)、对换性、虚拟性
    常规存储器:一次性、驻留性
  • 虚拟存储器的实现:分页请求系统、请求分段系统

第06章 输入输出系统

  • IO系统基本功能:隐藏物理设备细节、与设备的无关性、提高处理机和IO设备的利用率、对IO设备进行控制、确保对设备的正确共享、错误处理。
  • IO软件分四个层次
    用户层IO软件:实现与用户交互的接口
    设备独立性软件:实现用户程序与设备驱动器的统一接口、设备命名、设备保护、设备的分配与释放,为设备管理和数据传送提供必要存储空间。
    设备驱动程序:与硬件直接相关。
    中断处理程序
  • 缓冲区是一个存储区域,可以是专门的硬件存储器,但硬件成本较高。一般情况下更多是利用内存作为缓冲区。
  • 引入缓冲区的原因:
    ①缓和CPU和IO设备间速度不匹配的矛盾
    ②减少对CPU的中断频率,放宽对CPU中断响应时间的限制
    ③解决数据粒度不匹配问题
    ④提高CPU和IO设备之间的并行性

第07张 文件管理

  • 按文件的组织方式分类:顺序文件、索引文件、索引顺序文件
  • 文件控制块(FCB):
    基本信息类:文件名、文件物理位置、文件逻辑结构、文件的物理结构
    存取控制信息类:存取权限
    使用信息类:建立时间、文件上一次修改时间、当前使用信息

第08章 磁盘存储器的管理

  • 外存组织方式:连续组织方式、链接组织方式、索引组织方式
  • 连续组织:随着文件建立时的空间分配和文件删除时的空间回收,磁盘空间被分割成许多小块,这些较小的连续区难以用来存储文件。而外存的紧凑操作,所花费时间比内存多。
  • 链接组织方式:
    隐式链接:在文件目录的每个目录项中,都含有指向链接文件第一个盘快和最后一个盘快的指针。(只适合于顺序访问,如果随机访问是低效的)
    显式链接:把用于链接文件各物理块的指针显示的存放在内存的一张链接表中。

其他

  • CPU从目态转换为管态的唯一途径是中断。

猜你喜欢

转载自blog.csdn.net/weixin_39731083/article/details/81448280