操作系统

一、OS基础

1.什么是操作系统?

  • OS是管理计算机硬件与软件资源的程序,是计算机的基石。
  • 本质是一个运行在计算机上的软件程序,用来管理计算机硬件和软件资源。
  • OS屏蔽了硬件层的复杂性。
  • 内核是核心部分,负责系统的内存管理,硬件设备的管理以及应用程序的管理。内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。

2.系统调用

根据进程访问资源的特点,可以把进程在系统上的运行分为两个级别:

  1. 用户态:用户态运行的程序可以直接读取用户程序的数据。
  2. 系统态:系统态运行的进程或者程序几乎可以访问计算机的任何资源,不受限制。

那什么是系统调用?

我们运行的程序运行在用户态,调用操作系统提供的系统态级别的子功能需要用到系统调用。这些系统调用可以分为:

  • 设备管理:完成设备的请求或者释放,以及设备启动等功能。
  • 文件管理:完成文件的读、写、创建和删除。
  • 进程控制:完成进程的创建,撤销,阻塞和唤醒等功能。
  • 进程通信:完成进程间的消息传递或信号传递等功能。
  • 内存管理:完成内存的分配,回收以及获取作业占用牛才能大小及地址等等。

二、进程和线程

1.进程和线程的区别

一个进程中有多个线程,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈。

线程是进程划分成更小的运行单位,一个进程在其执行的过程可以产生多个线程。最大的不同在于各进程基本上是独立的,而线程不一定,因为同一进程的线程可能互相影响。线程执行开销更小,但不利于资源的管理和保护,进程刚好相反。

2.进程有哪几种状态

  • 创建状态:被创建中,未就绪。
  • 就绪状态:准备运行,获得除处理器之外的一切所需资源,once得到处理器资源就开始运行。
  • 运行状态:进程在处理器上运行。
  • 阻塞状态:等待状态,进程正在等待某一事件而暂停运行如等待某资源为可用或等待 IO 操作完成。即使处理器空闲,该进程也不能运行。
  • 结束状态:进程从系统中消失。可能是进程正常结束或者意外退出。

3.进程间的通信方式

  • 匿名管道:具有亲缘关系的父子进程或者兄弟进程之间通信。
  • 有名管道:遵循“FIFO”。以磁盘文件的方式存在,可以实现本机任意两个进程通信。
  • 信号:复杂,用于通知进程某个事件已经发生。
  • 消息队列:消息的链表,存放在内存中由消息队列标识符标识。管道和消息队列都是先进先出。与管道不同,MQ存在于内核中,只有重启内核(操作系统重启)或者显示删除一个消息队列,才会真正的被删除。MQ可以实现消息的随机查询,不一定要FIFO的次序取出。MQ克服了信号承载量少,管道只能承载无格式字节流以及缓冲区大小受限等缺陷。
  • 信号量:计数器,用于多进程共享数据的访问,目的是进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
  • 共享内存:多进程访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存数据的更新。依靠同步操作,如互斥锁和信号量等。是最有效的进程间的通信方式。
  • 套接字:客户端和服务器之间通过网络进行通信。套接字是支持TCP/IP的网络通信的基本操作单元。可以看做是不同主机之间的进程间进行双向通信的端点。通信的双方的一种约定,用套接字的相关函数来完成通信。

4.线程间的同步方式

  • 互斥量:互斥对象机制,拥有互斥对象的线程才能访问公共资源。因为互斥对象只有一个,保证资源不会被多个线程同时访问。比如java中的synchronized和各种lock就是这种机制。
  • 信号量:允许同一时刻多个线程访问同一个资源,但是需要控制同一时刻访问此资源的最大线程数量。
  • 事件:通过通知操作的方式来保护多线程同步,还可以方便的实现多线程优先级比较操作。

5.进程的调度算法

  • 先来先服务(FCFS):从就绪队列选择一个最先进入到该队列的进程分配资源,一直执行到完成或者发生事件阻塞放弃占用CPU时在重新调度。
  • 短作业优先(SJF):选择一个估计运行时间最短的进程分配资源。
  • 时间片轮转:最古老最简单的算法,又称为RR算法。每个进程分配一个时间片,即该进程允许运行的时间。
  • 多级反馈队列调度算法:前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
  • 优先级调度:为每个流程分配优先级。相同优先级的按照FCFS。

三、内存管理

1、操作系统的内存管理主要做什么?

负责内存的分配与回收(malloc:申请内存,free:释放内存),另外地址转换也就是将逻辑地址转化为相应的物理地址。

2、常见的内存管理机制?

连续分配管理方式和非连续分配管理方式。连续指的是为一个用户分配一个连续的内存空间。如块式管理。非连续方式允许一个程序使用的内存在离散或者不相邻的内存中,常见的比如页式管理段式管理

  • 块式管理:内存分成固定大小的块,一个块运行一个进程,如果进程需要的内存很小,则剩下的浪费。未利用的块成为碎片。
  • 页式管理:主存分为大小相等且固定的页,页较小,比块的划分力度大,提高内存占用率,减少碎片。通过页表对应逻辑地址和物理地址。
  • 段式管理:页提高利用率,但是页没意义。段式管理把主存分为一段一段的,比页小的多。段有意义,定义了一组逻辑信息。例如:主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。
  • 段页式管理:段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页,也就是说 段页式管理机制 中段与段之间以及段的内部的都是离散的。

分页机制和分段机制的共同点和区别

共同点:

  • 都是为了提高内存利用率,减少内存碎片化
  • 离散存储,两者都是离散分配内存的方式,但是,每个页和段中的内存是连续的。

区别:

  • 页大小固定,由OS决定,段大小不固定,取决于当前运行的程序。
  • 分页仅仅是为了满足操作系统内存管理的需求,而段是逻辑信息的单位,在程序中可以体现为代码段,数据段,能够更好满足用户的需要。

3、快表和多级页表

在操作系统中存在一个虚拟内存的概念,它用于内存的管理,使得应用程序认为它有一段连续的内存,大大地简化了程序员码代码的难度。程序员只用关注在这个连续的虚拟内存段中怎么使用内存,不用关心在物理内存中到底用那一段内存,进程运行的时候操作系统会自动进行映射。操作系统是怎么做到的呢?实际上操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表,页表的内容就是该进程的虚拟地址到物理地址的一个映射。

在分页内存管理中,很重要的两点是:虚拟地址到物理地址的转换要快以及解决虚拟地址空间大,页表也会很大的问题。

  • 快表:特殊的高速缓冲器,内容是页表的一部分或者全部。作用和页表相似,但是提高了访问速度。由于采用页表做地址转换,读写内存数据CPU要访问主频两次,有了快表,有时候只访问一次高速缓冲存储器,一次主存,可以加快寻找并提高指令执行速度。使用快表之后的转换流程是这样的:

    • 根据虚拟地址中的页号查找地址
    • 在快表,读取相应的物理地址
    • 不在,访问内存中的页表,同时添加到快表
    • 块表填满,按照一定的策略淘汰一个页。
  • 多级页表:避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表保存在内存中。属于时间换空间的典型场景。

    为了提高内存的空间性能,提出了多级页表的概念;但是提到空间性能是以浪费时间性能为基础的,因此为了补充损失的时间性能,提出了快表(即 TLB)的概念。 不论是快表还是多级页表实际上都利用到了程序的局部性原理,局部性原理在后面的虚拟内存这部分会介绍到。

4、逻辑地址和物理地址

我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。

5、CPU寻址,为什么需要虚拟地址空间?

现代处理器使用虚拟寻址的方式,需要内存管理单元来完成。

  • 为什么要虚拟地址空间呢?

    如果没有,程序直接访问操作物理内存,可能有的后果:

    • 程序访问任意内存,容易有意或无意破坏OS,造成崩溃。
    • 同时运行多个程序比较困难,比如,微信给内存地址1xxx赋值后,QQ也同样给1XXX赋值,那就覆盖了,然后微信程序崩溃。

    通过虚拟地址访问内存有以下优势:

    • 程序可以使用一系列相邻的虚拟地址来访问内存中不相邻的大内存缓冲区。
    • 程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘文件。数据或代码页会根据需要在物理内存与磁盘之间移动。
    • 不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存。

四、虚拟内存

虚拟内存是计算机系统内存管理的一种技术,我们可以手动设置电脑的虚拟内存。虚拟内存的重要意义是他定义了一个连续的寻你地址空间,并且把内存拓展到硬盘空间。

虚拟内存 使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如 RAM)的使用也更有效率。目前,大多数操作系统都使用了虚拟内存,如 Windows 家族的“虚拟内存”;Linux 的“交换空间”等。From:https://zh.wikipedia.org/wiki/虚拟内存

1.局部性原理

是虚拟内存的基础,正是因为局部性原理,才可以只装入部分程序到内存就可以开始运行。

局部性原理表现在以下方面:

  • 时间局限性:程序中的某条指令一旦执行,不久以后可能再次执行;如果数据在某个较短的时间被访问过,可能再次访问,原因是程序中存在大量的循环操作。
  • 空间局限性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。

时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是建立了 “内存一外存”的两级存储器的结构,利用局部性原理实现髙速缓存。

2.虚拟内存

基于局部性原理,程序装入时,先将一部分装入内存,其他部分留在外存。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器

是一种时间换空间的策略,利用cup计算时间,页的调入调出时间来换更大的空间支持程序运行。程序的世界,不是时间换空间就是空间换时间。

3.虚拟内存的技术实现

虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。

  • 请求分页存储管理:建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。
  • 请求分段存储管理:建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。
  • 请求段页式存储管理

请求分页存储管理建立在分页管理之上。他们的根本区别是是否将程序全部所需的全部地址空间都装入主存,这也是请求分页存储管理可以提供虚拟内存的原因,我们在上面已经分析过了。

它们之间的根本区别在于是否将一作业的全部地址空间同时装入主存。请求分页存储管理不要求将作业全部地址空间同时装入主存。基于这一点,请求分页存储管理可以提供虚存,而分页存储管理却不能提供虚存。

不管哪种实现方式,都需要:

  • 一定容量的内存和外存。
  • 缺页中断:如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页面或段调入到内存,然后继续执行程序;
  • 虚拟地址空间:逻辑地址到物理地址的转换。

4.页面置换算法

地址映射的过程中,若在页面中发现需要访问的页面不在内存中,则发生缺页中断。

缺页中断 就是要访问的不在主存,需要操作系统将其调入主存后再进行访问。 在这个时候,被内存映射的文件实际上成了一个分页交换文件。

缺页中断时,若当前没存没有空闲的页面,淘汰一页,称为页面置换算法。

  • OPT页面置换算法(最佳页面置换算法):所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。
  • FIFO:淘汰最先进入内存的页面。
  • LRU(最近最久未使用):访问字段记录页面上次被访问以来的时间T,淘汰T值最大的。
  • LFU(最少使用页面):之前时期使用最少的页面淘汰。

常见问题

PE文件

全称是Portable Exexutable,可移植的可执行文件,常见的如EXE,DLL,OCX,SYS,是windows操作系统上的程序文件。

活锁和死锁

活:任务或执行者没有被阻塞,但由于某些条件没有满足,导致一直重复尝试,失败。区别在于处于活锁的实体是在不断的改变状态,处于死锁的实体表现为等待;活锁可以自行解开,死锁不可。

活锁是一系列进程在轮训的等待某个不可能为真的条件为真。进程不会blocked,这会导致CPU资源耗尽。

解决活锁可以引进一些随机性,检测到冲突就暂停一定时间进行重试。大大减少碰撞的可能性。

直接寻址和间接寻址

寻址就是处理器根据指令中给出的地址信息来寻找物理地址的方式,是确定本条指令的数据地址以及下一条要执行的指令地址的方法。

  • 指令寻址:在内存中查找指令
    • 顺序:采用PC计数器来计数指令的顺序。
    • 跳跃:下条程序的地址码不是程序计数器给出,而是本条指令给出。
  • 操作数寻址:形成操作数的有效地址
    • 立即寻址:操作数作为指令的一部分直接写在指令中。
    • 直接寻址:基本的寻址方法,在指令格式的地址的字段中直接指出操作数在内存的地址。由于操作数的地址直接给出而不需要经过某种变换,所以称这种寻址方式为直接寻址方式。
    • 间接寻址:间接寻址是相对直接寻址而言的,在间接寻址的情况下,指令地址字段中的形式地址不是操作数的真正地址,而是操作数地址的指示器,或者说此形式地址单元的内容才是操作数的有效地址

实时操作系统和分时操作系统

  • 分时:多个联机用户同时适用一个计算机系统在各自终端上进行交互式会话,程序、数据和命令均在会话过程中提供,以问答方式控制程序运行。系统把处理器的时间划分为时间片轮流分配给各个连接终端。
  • 实时:当外部时间或数据产生时,能够对其予以接受并以足够快的速度进行处理,所得结果能够在规定时间内控制生产过程或对控制对象作出快速响应,并控制所有实时任务协调的操作系统。因而,提供及时响应和高可靠性是其主要特点
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

请我喝杯咖啡吧~

支付宝
微信