操作系统(Operating System)

一、计算机系统概述

在这里插入图片描述

什么是操作系统(操作系统的概念)

操作系统(Operating System, OS)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统软件。
在这里插入图片描述

操作系统的目标和功能

在这里插入图片描述

  1. 操作系统是计算机资源的管理者
    a. 处理机管理(进程控制、进程同步、进程通信、死锁处理、处理机调度)
    b. 存储器管理(提高内存利用率,内存的分配与回收、地址映射、内存保护与共享、内存扩充)
    c. 文件管理(计算机中的信息都是以文件的形式存在的)
    d. 设备管理(完成用户的I/O请求,方便用户使用设备、并提高设备的利用率)
  2. 操作系统为用户提供使用计算机硬件系统的接口
    a. 命令接口(用户通过控制台或终端输入操作命令,向系统提供各种服务要求)
    b. 程序接口(由系统调用组成,用户在程序中使用这些系统调用来请求操作系统为其提供服务)
    c. 图形接口最常见的图形用户界面GUI(最终还是通过调用程序接口实现的)
  3. 操作系统用作扩充机器
    没有任何软件支持的计算机称为裸机,实际呈现在用户面前的计算机系统是经过若干层软件改造的计算机。操作系统将裸机改造成功能更强、使用更方便的机器。我们将覆盖了软件的机器称为扩充机器或虚拟机。

操作系统的作用,提供了什么服务(在计算机系统中操作系统主要起的作用是什么) ※※

  1. 处理机管理
  2. 存储器管理
  3. 设备管理
  4. 文件管理
  5. 用户接口

操作系统的四个特征 ※

  1. 并发
  2. 共享
  3. 虚拟
  4. 异步

内核态和用户态的区别 ※

内核态=核心态=管态
用户态=目态

CSDN链接

  1. 用户态可以执行cpu调用的非特权指令
  2. 内核态可以执行特权指令和非特权指令
  3. 用户态到内核态的切换是通过中断实现的
  4. 内核态到用户态的切换是通过特权指令实现的

内核态 → 用户态:执行一条特权指令——修改PSW的标志位为“用户态”,这个动作意味着操作系统将主动让出CPU使用权
用户态 → 内核态:由“中断”引发,硬件自动完成变态过程,触发中断信号意味着操作系统将强行夺回CPU的使用权

操作系统的运行机制

在这里插入图片描述

为什么说操作系统是由中断驱动的?

链接
中断是操作系统的核心技术之一,最关键的原因是,现代操作系统必须具备的多线程、多进程技术都是基于中断技术实现的,无论是windows的任务抢先式分配cpu还是linux的分时分配cpu,首先都需要定时中断的参与,才能让系统得到cpu执行时间,然后系统才能根据各自的算法启动等待队列里面的进程或线程。

链接
操作系统是一个众多程序模块的集合,而这些程序模块分为三类:
第一类是系统启动后主动与用户态程序并发执行,而所有并发程序都是有中断驱动的;
第二类是一些通过系统调用指令“被动”地为用户服务的程序,而系统调用指令的执行是经中断机构处理的;第三类是隐藏在操作系统内部即不主动运行,也不直接面对用户态程序的程序,它们由前两类程序调用的。综合上述,可得操作系统是由中断驱动的。

中断 ※

  1. 中断的引入——为了支持CPU和设备之间的并行操作
    中断也称外中断,指来自CPU执行指令以外的事件的发生,如设备发出的I/O结束中断、时钟中断等。这一类中断通常是与当前执行的指令无关的事件。
  2. 当发生中断时,CPU立即进入内核态
  3. 当发生中断后,当前进程暂停运行,并由操作系统内核对中断进行处理
  4. 对于不同的中断信号,会进行不同的处理
  5. 中断分为内中断和外中断。

异常

异常的引入——表示CPU执行指令本身时出现的问题
异常也称内中断、例外或陷入,指源自CPU执行指令内部的事件,如程序的非法操作码、地址越界、算术溢出、缺页异常等。对异常的处理一般要依赖与当前程序的运行现场,不能被屏蔽。

中断和异常的联系与区别

在这里插入图片描述

系统调用

计算机系统的各种硬件资源是有限,为了更好的管理这些资源,进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用。一般地,系统调用都是通过中断实现的,比如,linux下中断号0x80就是进行系统调用的。
操作系统为用户态进程与硬件设备进行交互提供了一组接口——系统调用:1.把用户从底层的硬件编程中解放了出来;2.极大地提高了系统的安全性使用户程序具有可移植性;用户程序与具体硬件已经被抽象接口所替代。

二、进程管理

在这里插入图片描述

进程与PCB

在这里插入图片描述
在这里插入图片描述

进程和线程的区别 ※※※※

  1. 进程(Process)是系统进行资源分配和调度的基本单位,线程(Thread)是CPU调度和分配的基本单位;
  2. 线程依赖于进程而存在,一个进程至少有一个线程
  3. 进程有自己的独立地址空间,线程共享所属进程的地址空间
  4. 进程是拥有系统资源的一个独立单位,而线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),和其他线程共享本进程的相关资源如内存、I/O、cpu等;
  5. 在进程切换时,涉及到整个当前进程CPU环境的保存环境的设置以及新被调度运行的CPU环境的设置,而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,可见,进程切换的开销远大于线程切换的开销
  6. 线程之间的通信更方便,同一进程下的线程共享全局变量等数据,而进程之间的通信需要以进程间通信(IPC)的方式进行;
  7. 多线程程序只要有一个线程崩溃,整个程序就崩溃了,但多进程程序中一个进程崩溃并不会对其它进程造成影响,因为进程有自己的独立地址空间,因此多进程更加健壮。

进程和程序的区别 ※

(1) 程序是永存的;进程是暂时的,是程序在数据集上的一次执行,有创建有撤销,存在是暂时的;
(2)程序是静态的观念,进程是动态的观念
(3)进程具有并发性,而程序没有;
(4)进程是竞争计算机资源的基本单位,程序不是。
(5)进程和程序不是一一对应的: 一个程序可对应多个进程即多个进程可执行同一程序; 一个进程可以执行一个或几个程序

作业与进程的区别

链接
一个进程是一个程序对某个数据集的执行过程,是分配资源的基本单位。作业是用户需要计算机完成的某项任务,是要求计算机所做工作的集合。一个作业的完成要经过作业提交、作业收容、作业执行和作业完成4个阶段。而进程是对已提交完毕的程序所执行过程的描述,是资源分配的基本单位。其主要区别如下:

(1)作业是用户向计算机提交任务的任务实体。在用户向计算机提交作业后,系统将它放入外存中的作业等待队列中等待执行。而进程则是完成用户任务的执行实体,是向系统申请分配资源的基本单位。任一进程,只要它被创建,总有相应的部分存在于内存中。

(2)一个作业可由多个进程组成,且必须至少由一个进程组成,反过来则不成立。

(3)作业的概念主要用在批处理系统中,像UNIX这样的分时系统中就没有作业的概念。而进程的概念则用在几乎所有的多道程序系统中。

进程的通信方式 ※

  1. 共享内存
    顾名思义,共享内存就是两个进程同时共享一块内存,然后在这块内存上的数据可以共同修改和读取,达到通信的目的。
  2. 无名管道
    无名管道是半双工的通信方式;并且只能在具有亲缘关系的进程之间使用(亲缘关系是指进程间的父子关系,兄弟关系等),具有亲缘关系的进程在创建时同时拥有一个无名管道的句柄,可以进行读写;无名管道不存在磁盘节点,只存在与内存中用完即销毁。
  3. 命名管道
    命名管道也是半双工的通信方式;可以在不具有亲缘关系的进程间通信;有名管道存在磁盘节点,有对应的FIFO文件,凡是可以访问该路径的文件的进程均可以进行通信。
  4. 消息队列
    消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  5. 套接字
    套接字是网络编程的api,通过套接字可以让不同的机器间的进程进行通信,常用于客户端进程和服务器进程的通信。
  6. 信号
    信号是Unix系统中使用的最古老的进程间通信的方法之一。操作系统通过信号来通知进程系统中发生了某种预先规定好的事件(一组事件中的一个),它也是用户进程之间通信和同步的一种原始机制。一个键盘中断或者一个错误条件(比如进程试图访问它的虚拟内存中不存在的位置等)都有可能产生一个信号。Shell也使用信号向它的子进程发送作业控制信号。

进程的五种状态及转换过程 ※

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进程(作业)的调度算法有哪些? ※※※※

  1. 先来先服务 first-come first-serverd(FCFS)
    按照请求的顺序进行调度。非抢占式,开销小,无饥饿问题,响应时间不确定(可能很慢);
    对短进程不利,对IO密集型进程不利。
  2. 短作业优先 shortest job first(SJF)
    按估计运行时间最短的顺序进行调度。非抢占式,吞吐量高,开销可能较大,可能导致饥饿问题;
    对短进程提供好的响应时间,对长进程不利,如果一直有短作业过来,那么长作业就会永远得不到调度。
  3. 最高响应比优先
    响应比 = 1+ 等待时间/处理时间。同时考虑了等待时间的长短和估计需要的执行时间长短,很好的平衡了长短进程。非抢占,吞吐量高,开销可能较大,提供好的响应时间,无饥饿问题。
  4. 优先级调度算法
    为每个进程分配一个优先级,按优先级进行调度。为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级。
  5. 时间片轮转
    将所有就绪进程按 FCFS 的原则排成一个队列,用完时间片的进程排到队列最后。抢占式(时间片用完时),开销小,无饥饿问题,为短进程提供好的响应时间;
    若时间片小,进程切换频繁,吞吐量低;若时间片太长,实时性得不到保证。
  6. 多级反馈队列调度算法
    设置多个就绪队列1、2、3…,优先级递减,时间片递增。只有等到优先级更高的队列为空时才会调度当前队列中的进程。如果进程用完了当前队列的时间片还未执行完,则会被移到下一队列。
    抢占式(时间片用完时),开销可能较大,对IO型进程有利,可能会出现饥饿问题。

进程同步 ※

为什么需要进程同步:进程有时候会和其他进程共享一些资源,比如内存、数据库等。当多个进程同时读写同一份共享资源的时候,可能会发生冲突。因此需要进程的同步,多个进程按顺序访问资源。

互斥量 Mutex:
互斥量是内核对象,只有拥有互斥对象的线程才有访问互斥资源的权限。因为互斥对象只有一个,所以可以保证互斥资源不会被多个线程同时访问;当前拥有互斥对象的线程处理完任务后必须将互斥对象交出,以便其他线程访问该资源;
信号量 Semaphore:
信号量是内核对象,它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。信号量对象保存了最大资源计数和当前可用资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就减1,只要当前可用资源计数大于0,就可以发出信号量信号,如果为0,则将线程放入一个队列中等待。线程处理完共享资源后,应在离开的同时通过 ReleaseSemaphore 函数将当前可用资源数加1。如果信号量的取值只能为0或1,那么信号量就成为了互斥量;
事件 Event:
允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。事件分为手动重置事件和自动重置事件。手动重置事件被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态,直到程序重新把它设置为未激发状态。自动重置事件被设置为激发状态后,会唤醒一个等待中的线程,然后自动恢复为未激发状态。
临界区 Critical Section:
指的是访问资源的那段代码,任意时刻只允许一个线程对临界资源进行访问。拥有临界区对象的线程可以访问该临界资源,其它试图访问该资源的线程将被挂起,直到临界区对象被释放。

死锁 ※

定义

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

死锁原因

① 系统资源不足(对不可剥夺资源的竞争)
② 进程推进顺序不当(P1拥有A申请B,P2拥有B申请A)

产生死锁的必要条件

① 互斥条件
指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。
② 请求和保持条件
指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
③ 不剥夺条件
指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放
④ 环路等待条件
指在发生死锁时,必然存在一个进程资源的环形链。

处理死锁的基本方法

① 预防死锁
这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。
② 避免死锁
该方法同样是属于事先预防的策略,但它并不须事先采取各种限制措施去破坏产生死锁的的四个必要条件,而是在资源的动态分配过程中,用 某种方法去防止系统进入不安全状态,从而避免发生死锁。
③ 检测死锁
这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源,然后采取适当措施,从系统中将已发生的死锁清除掉。
④ 解除死锁
这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。

三、内存管理

在这里插入图片描述

内存扩充技术——覆盖技术和交换技术 ※

覆盖技术
把一个大的程序划分为一系列覆盖,每个覆盖是一个相对独立的程序单位,把程序执行时并不要求同时 装入内存的覆盖组成一组,成为覆盖段,这个覆盖段分配到同一个存储区域,这个存储区域成为覆盖区,它与覆盖段一一对应。覆盖段的大小由覆盖段中最大的覆盖来确定。(为了解决内存容量太小的问题,打破了必须将一个程序全部信息装入内存后才能运行的限制)

交换技术
把暂时不用的某个程序及数据部分从内存移到外存中去,以便腾出必要的内存空间;或者把指定的程序或数据从外存读到相应的内存中,并将控制权交给他,让其在系统上运行的一种内存扩充技术。处理器的中级调度就是采用交换技术。

区别:
① 与覆盖技术相比,交换技术不要求程序员给出的 程序段之间的覆盖结构;
② 交换技术主要在进程和作业之间进行,覆盖技术主要在同一个进程或作业中进行;交换技术主要在进程和作业之间进行,覆盖技术主要在同一个进程或作业中进行;
③ 覆盖技术只能覆盖于覆盖程序段无关的程序段,交换进程由换出和换入两个过程组成。覆盖技术只能覆盖于覆盖程序段无关的程序段,交换进程由换出和换入两个过程组成。

分页和分段的区别 ※

链接
页和分段系统有许多相似之处,但在概念上两者完全不同,主要表现在:
1、页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。
段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需要。
2、页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。
段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。
3、分页的作业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。
分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名(段号),又需给出段内地址(段地址)。

CPU的寻址方式 ※

链接
寻址方式就是处理器根据指令中给出的地址信息来寻找有效地址的方式,是确定本条指令的数据地址以及下一条要执行的指令地址的方法。在存储器中,操作数或指令字写入或读出的方式,有地址指定方式、相联存储方式和堆栈存取方式。几乎所有的计算机,在内存中都采用地址指定方式。当采用地址指定方式时,形成操作数或指令地址的方式称为寻址方式。
寻址方式分为两类,即指令寻址方式和数据寻址方式,前者比较简单,后者比较复杂。值得注意的是,在传统方式设计的计算机中,内存中指令的寻址与数据的寻址是交替进行的。

指令寻址:

  1. 顺序寻址
  2. 跳跃寻址

数据寻址:

  1. 隐含寻址
  2. 立即寻址
  3. 直接寻址
  4. 间接寻址
  5. 相对寻址
  6. 基址寻址
  7. 变址寻址

堆和栈的区别 ※※

链接
(1)管理方式不同。
栈编译器自动管理,无需程序员手工控制;而堆空间的申请释放工作由程序员控制,容易产生内存泄漏。

(2)空间大小不同。
栈是向低地址扩展的数据结构,是一块连续的内存区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,当申请的空间超过栈的剩余空间时,将提示溢出。因此,用户能从栈获得的空间较小。

堆是向高地址扩展的数据结构,是不连续的内存区域。因为系统是用链表来存储空闲内存地址的,且链表的遍历方向是由低地址向高地址。由此可见,堆获得的空间较灵活,也较大。栈中元素都是一一对应的,不会存在一个内存块从栈中间弹出的情况。

(3)是否产生碎片。
对于堆来讲,频繁的malloc/free(new/delete)势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低(虽然程序在退出后操作系统会对内存进行回收管理)。对于栈来讲,则不会存在这个问题。

(4)增长方向不同。
堆的增长方向是向上的,即向着内存地址增加的方向;栈的增长方向是向下的,即向着内存地址减小的方向。

(5)分配方式不同。
堆都是程序中由malloc()函数动态申请分配并由free()函数释放的;栈的分配和释放是由编译器完成的,栈的动态分配由alloca()函数完成,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行申请和释放的,无需手工实现。

(6)分配效率不同。
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行。堆则是C函数库提供的,它的机制很复杂,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大的空间,如果没有足够大的空间(可能是由于内存碎片太多),就有需要操作系统来重新整理内存空间,这样就有机会分到足够大小的内存,然后返回。显然,堆的效率比栈要低得多。

递归栈会不会溢出,为什么

链接
递归调用,只有走到最后的结束点后函数才能依次退出,而未到达最后的结束点之前,占用的栈空间一直没有释放,如果递归调用次数过多,就可能导致占用的栈资源超过线程的最大值,从而导致栈溢出,导致程序的异常退出。

链接
栈的出入规则,先入后出,如果先入的一直不能出栈,则会一直存在栈空间中,这样就容易导致栈满而溢出。

栈泄漏是什么

链接
栈溢出是指向向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行。

四、文件管理

在这里插入图片描述

磁盘调度算法有哪些? ※※

1、先来先服务算法(FCFS)First Come First Service
这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。
此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。
此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。
2、最短寻道时间优先算法(SSTF) Shortest Seek Time First
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。
3、扫描算法(SCAN)电梯调度
扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到再无更外的磁道需要访问才将磁臂换向,自外向里移动。这时,同样也是每次选择这样的进程来调度,即其要访问的磁道,在当前磁道之内,从而避免了饥饿现象的出现。由于这种算法中磁头移动的规律颇似电梯的运行,故又称为电梯调度算法。此算法基本上克服了最短寻道时间优先算法的服务集中于中间磁道和响应时间变化比较大的缺点,而具有最短寻道时间优先算法的优点即吞吐量较大,平均响应时间较小,但由于是摆动式的扫描方法,两侧磁道被访问的频率仍低于中间磁道。
4、循环扫描算法(CSCAN)
循环扫描算法是对扫描算法的改进。如果对磁道的访问请求是均匀分布的,当磁头到达磁盘的一端,并反向运动时落在磁头之后的访问请求相对较少。这是由于这些磁道刚被处理,而磁盘另一端的请求密度相当高,且这些访问请求等待的时间较长,为了解决这种情况,循环扫描算法规定磁头单向移动。例如,只自里向外移动,当磁头移到最外的被访问磁道时,磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。

五、输入输出管理

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41286942/article/details/123711437