操作系统概念

操作系统概念

  • 什么是操作系统
    • 操作系统的功能组成
    • 操作系统主要特征
  • 系统调用
  • 进程和线程
    • 进程和线程的区别
      • 从三个角度来剖析二者之间的区别
    • 什么是协程
    • 协程与线程进行比较
    • 进程调度功能
      • 调度方式
      • 调度算法
      • 进程有哪几种状态
    • 进程间同步方式
      • 临界区概念
      • 同步与互斥的概念
    • 进程间的通信方式
    • 线程间的同步方式
  • 什么是死锁
    • 死锁产生的必要条件
      • 死锁起因
  • 操作系统内存管理基础
    • 内存管理介绍
      • 常见的几种内存管理机制
        • 快表和多级页表
      • 分页机制和分段机制的共同点和区别
  • 虚拟内存
    • 基本特征
    • 如何进行地址空间到物理内存的映射
    • 有哪些页面置换算法
  • 什么是IO多路复用?怎么实现
    • select/poll/epoll三者的区别
    • 什么时候使用select/poll,什么时候使用epoll
    • 什么是水平触发?什么是边缘触发
    • 有哪些常见的IO模型

什么是操作系统

  • 操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的程序,是计算机系统的内核与基石;
  • 操作系统本质上是运行在计算机上的软件程序 ;
  • 操作系统为用户提供一个与系统交互的操作界面 ;

操作系统的功能组成

  • 用户和接口管理: 负责用户身份核准、操作权限管理以及各种人机接口的实现。
  • 处理机管理: 围绕CPU的调度,负责管理、控制用户程序的动态执行过程
    • 进程控制和管理;进程同步和互斥;进程通信;进程死锁;线程控制和管理;四级调度。
  • 存储管理: 负责为正在运行的程序分配内存空间,并实现地址和空间有关的管理功能
    • 内存分配;地址转换;存储保护;内存共享;存储扩充
  • 设备管理: 负责外存和I/O设备的分配、驱动和调度控制,以及实现外设读写的相关机制。
    • 设备的分配和回收;设备的驱动调度;实现逻辑设备到物理设备之间的映射;
    • 提供设备中断处理;提供缓冲区管理;实现虚拟设备;
  • 文件管理: 负责文件的建立、存取、目录管理、共享保护以及文件存储空间的管理。
    • 提供文件的逻辑组织方法;提供文件的物理组织方法;提供文件的存取和使用方法;
    • 实现文件的目录管理;实现文件的共享和安全性控制;实现文件的存储空间管理
  • 网络与通信管理等

操作系统主要特征

  • 并发性(Concurrency):在一个时间段内,多个程序处于宏观的运行状态,并发推进。
  • 共享性(Sharing): 共享性指操作系统中的资源可被多个并发执行的进程所使用 。
  • 异步性(Async):异步性也被称为不确定性,指的是并发进程的推进速度不可预知。每个进程在某一时刻所处的状态以及资源拥有情况,不是提前安排好的,而是系统动态运行过程中通过管理调度形成的。
    • 异步性特征是并发和共享带来的结果。
  • 虚拟性(Virtuality):虚拟性是指利用某种技术将少的物理资源演变为多的、逻辑上的对应资源;

系统调用

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

  • 用户态(user mode) : 用户态运行的进程或可以直接读取用户程序的数据。只能受限地访问内存,且不允许访问外围设备,没有占用CPU的能力,CPU资源可以被其它程序获取;
  • 系统态(kernel mode):可以简单的理解系统态运行的进程或程序几乎可以访问计算机的任何资源,不受限制。

我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能咋办呢?那就需要系统调用了!

系统调用:是应用程序与OS的接口, 也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。

系统调用按功能大致可分为如下几类:

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

进程和线程

进程和线程的区别

  • 进程是什么

    • 进程是具有一定独立功能的程序、它是系统进行资源分配和调度的一个独立单位,也就是说进程是可以独立运行的一段程序
      • a. 从原理角度看,进程是支持程序执行的一种系统机制,它对处理器上运行程序的活动进行抽象
      • b. 从实现角度看,进程是一种数据结构,用来准确地刻画运行程序的状态和系统动态变化状况
  • 线程是什么

    • 线程进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源。在运行时,只是暂用一些计数器、寄存器和栈 。
  • 操作系统中引入进程的目的是为了使多个程序并发执行,以改善资源使用率和提高系统效率

  • 操作系统中再引入线程,则是为了减少程序并发执行时所付出的时空开销,使得并发粒度更细、并发性更好。

从三个角度来剖析二者之间的区别

  • 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
  • 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行
  • 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源

什么是协程

协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

协程与线程进行比较

  • 一个线程可以拥有多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
  • 线程进程都是同步机制,而协程则是异步
  • 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态

进程调度功能

  • 根据进程当前状态决定哪个进程获得CPU,以及占用多长时间。
  • 将CPU分给进程。

调度方式

  • 非抢占式调度: 当前进程主动放弃处理机控制权
  • 抢占式调度:主要指在系统正常运转期间,如果某种事件出现,系统将迫使正在运行的进程停下来,将CPU控制权交给其它进程。

调度算法

进程的调度算法是为了确定首先执行哪个进程以及最后执行哪个进程以实现最大CPU利用率,有以下几类

  • 先到先服务(FCFS)调度算法 : 从就绪队列中选择一个最先进入该队列的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度。
  • 短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU时再重新调度。
    时间片轮转调度算法 : 时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法,又称RR(Round robin)调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
  • 多级反馈队列调度算法 :前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程 。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业(进程)迅速完成。,因而它是目前被公认的一种较好的进程调度算法,UNIX操作系统采取的便是这种调度算法。
  • 优先级调度 :为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以FCFS方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。

进程有哪几种状态

  • 运行状态 :进程得到CPU控制权,它的程序正在运行。(在系统中,总只有一个进程处于此状态)
  • 就绪状态:已经准备就绪,一旦得到CPU,就立即可以运行。(有多个进程处于此状态)
  • 阻塞状态:正在等待某个事件的发生(如等待I/O的完成),而暂停执行,这时,即使给它CPU时间,它也无法执行。

操作系统概念_第1张图片

进程间同步方式

进程的同步是目的,而进程间通信是实现进程同步的手段

临界区概念

  • 并发进程中与共享变量有关的程序段称为临界区(Critical Section)。
  • 共享变量所代表的资源称为临界资源(Critical Resource),即一次仅能供一个进程使用的资源。

同步与互斥的概念

  • 同步:多个进程因为合作而使得进程的执行有一定的先后顺序。比如某个进程需要另一个进程提供的消息,获得消息之前进入阻塞态;体现协作关系。
  • 互斥:多个进程在同一时刻只有一个进程能进入临界区,体现竞争关系

进程间的通信方式

  • 管道/匿名管道(Pipes) :用于具有亲缘关系的父子进程间或者兄弟进程之间的通信。
  • 有名管道(Names Pipes) : 匿名管道由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
  • 信号(Signal) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生,比如 Linux 中的 SIGKILL信号
  • 消息队列(Message Queuing) :消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)不同的是消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺。
  • 信号量(Semaphores) :信号量是一个计数器,用于多进程对共享数据的访问,信号量的意图在于进程间同步。这种通信方式主要用于解决与同步相关的问题并避免竞争条件。
  • 共享内存(Shared memory) :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。
  • 套接字(Sockets) : 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

操作系统概念_第2张图片

线程间的同步方式

线程同步是两个或多个共享关键资源的线程的并发执行。应该同步线程以避免关键的资源使用冲突。操作系统一般有下面三种线程同步的方式:

  • 互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的 synchronized 关键词和各种 Lock 都是这种机制。
  • 信号量(Semphares) :它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量
  • 事件(Event) :Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操做
  • 临界区 Critical Section:任意时刻只允许一个线程对临界资源进行访问。拥有临界区对象的线程可以访问该临界资源,其它试图访问该资源的线程将被挂起,直到临界区对象被释放。

什么是死锁

在两个或者多个并发进程中,每个进程持有某种资源而又等待其它进程释放它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁(deadlock)。

死锁产生的必要条件

  • 互斥:一个资源一次只能被一个进程使用;
  • 占有并等待:一个进程至少占有一个资源,并在等待另一个被其它进程占用的资源;
  • 非抢占:已经分配给一个进程的资源不能被强制性抢占,只能由进程完成任务之后自愿释放;
  • 循环等待:若干进程之间形成一种头尾相接的环形等待资源关系,该环路中的每个进程都在等待下一个进程所占有的资源。

死锁起因

  • 资源不足
  • 进程推进顺序非法

操作系统内存管理基础

内存管理介绍

  • 内存分配:操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释放内存)
  • 地址映射: 地址映射也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
  • 内存保护: 检查地址的合法性,防止越界访问
  • 内存扩充: 解决“求大于供”的问题,采用虚拟存储技术

常见的几种内存管理机制

  • 简单分为连续分配管理方式和非连续分配管理方式这两种。

    • 连续分配管理方式是指为一个用户程序分配一个连续的内存空间,常见的如 块式管理 。
    • 非连续分配管理方式允许一个程序使用的内存分布在离散或者说不相邻的内存中,常见的如页式管理 和 段式管理。
  • 块式管理 :将内存分为几个固定大小的块,每个块中只包含一个进程。如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间,我们称之为碎片。

  • 页式管理 :把主存分为大小相等且固定的一页一页的形式,页较小,相对相比于块式管理的划分力度更大,提高了内存利用率,减少了碎片。页式管理通过页表对应逻辑地址和物理地址。这里有两点需要注意: 1
    虚拟地址到物理地址的转换要快。2.虚拟地址空间大,页表也会很大的问题。

  • 段式管理 :页式管理虽然提高了内存利用率,但是页式管理其中的页实际并无任何实际意义。段式管理把主存分为一段段的,每一段的空间又要比一页的空间小很多 。但是,最重要的是段是有实际意义的,每个段定义了一组逻辑信息,例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。段式管理通过段表对应逻辑地址和物理地址。

  • 段页式管理机制: 段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段,每个段又分成若干页

快表和多级页表
  • 快表

为了解决虚拟地址到物理地址的转换速度,操作系统在 页表方案 基础之上引入了 快表 来加速虚拟地址到物理地址的转换(用来存放进程最近访问的部分页表项)。我们可以把块表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的Cache,它的作用与页表相似,但是提高了访问速率。由于采用页表做地址转换,读写内存数据时CPU要访问两次主存。有了快表,有时只要访问一次高速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。

使用快表之后的地址转换流程是这样的:

  • 根据虚拟地址中的页号查快表;

  • 如果该页在快表中,直接从快表中读取相应的物理地址;

  • 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;

  • 当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。

  • 多级页表

引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。

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

  • 共同点 :

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

  • 区别 :

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

虚拟内存

每个程序都拥有自己的地址空间,这个地址空间被分成大小相等的页,这些页被映射到物理内存;但不需要所有的页都在物理内存中,当程序引用到不在物理内存中的页时,由操作系统将缺失的部分装入物理内存。这样,对于程序来说,逻辑上似乎有很大的内存空间,只是实际上有一部分是存储在磁盘上,因此叫做虚拟内存。

基本特征

  • 虚拟扩充:不是物理上,而是逻辑上扩充了内存容量
  • 部分装入: 每个作业(进程)不是全部一次性地装入内存,而是只装入其一 部分
  • 离散分配: 每个作业(进程)装入内存的那部分不必占用连续的内存空间,而是“见缝插针”
  • 多次对换: 在一个进程运行期间,它所需的全部程序和数据要分成多次调入内存

如何进行地址空间到物理内存的映射

内存管理单元(MMU)管理着逻辑地址和物理地址的转换,其中的页表(Page table)存储着页(逻辑地址)和页框(物理内存空间)的映射表,页表中还包含包含有效位(是在内存还是磁盘)、访问位(是否被访问过)、修改位(内存中是否被修改过)、保护位(只读还是可读写)。逻辑地址:页号+页内地址(偏移);每个进程一个页表,放在内存,页表起始地址在PCB/寄存器中。

有哪些页面置换算法

在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断从而将该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘中来腾出空间。页面置换算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。

  • 最佳页面置换算法OPT(Optimal replacement algorithm):置换以后不需要或者最远的将来才需要的页面,是一种理论上的算法,是最优策略;
  • 先进先出FIFO:置换在内存中驻留时间最长的页面。缺点:有可能将那些经常被访问的页面也被换出,从而使缺页率升高;
  • 第二次机会算法SCR:按FIFO选择某一页面,若其访问位为1,给第二次机会,并将访问位置0;
  • 时钟算法 Clock:SCR中需要将页面在链表中移动(第二次机会的时候要将这个页面从链表头移到链表尾),时钟算法使用环形链表,再使用一个指针指向最老的页面,避免了移动页面的开销;
  • 最近未使用算法NRU(Not Recently Used):检查访问位R、修改位M,优先置换R=M=0,其次是(R=0, M=1);
  • 最近最少使用算法LRU(Least Recently Used):置换出未使用时间最长的一页;实现方式:维护时间戳,或者维护一个所有页面的链表。当一个页面被访问时,将这个页面移到链表表头。这样就能保证链表表尾的页面是最近最久未访问的。
  • 最不经常使用算法NFU:置换出访问次数最少的页面

什么是IO多路复用?怎么实现

IO多路复用(IO Multiplexing)是指单个进程/线程就可以同时处理多个IO请求。

实现原理:用户将想要监视的文件描述符(File Descriptor)添加到select/poll/epoll函数中,由内核监视,函数阻塞。一旦有文件描述符就绪(读就绪或写就绪),或者超时(设置timeout),函数就会返回,然后该进程可以进行相应的读/写操作。

select/poll/epoll三者的区别

  • select:
    • 将文件描述符放入一个集合中,调用select时,将这个集合从用户空间拷贝到内核空间(缺点1:每次都要复制,开销大),由内核根据就绪状态修改该集合的内容。(缺点2)集合大小有限制,32位机默认是1024(64位:2048);
    • 采用水平触发机制。select函数返回后,需要通过遍历这个集合,找到就绪的文件描述符(缺点3:轮询的方式效率较低),当文件描述符的数量增加时,效率会线性下降
  • poll:和select几乎没有区别,区别在于文件描述符的存储方式不同,poll采用链表的方式存储,没有最大存储数量的限制;
  • epoll:
    • 通过内核和用户空间共享内存,避免了不断复制的问题;支持的同时连接数上限很高(1G左右的内存支持10W左右的连接数);
    • 文件描述符就绪时,采用回调机制,避免了轮询(回调函数将就绪的描述符添加到一个链表中,执行epoll_wait时,返回这个链表);
    • 支持水平触发和边缘触发,采用边缘触发机制时,只有活跃的描述符才会触发回调函数。

总结,区别主要在于:

  • 一个线程/进程所能打开的最大连接数
  • 文件描述符传递方式(是否复制)
  • 水平触发 or 边缘触发
  • 查询就绪的描述符时的效率(是否轮询)

什么时候使用select/poll,什么时候使用epoll

当连接数较多并且有很多的不活跃连接时,epoll的效率比其它两者高很多;但是当连接数较少并且都十分活跃的情况下,由于epoll需要很多回调,因此性能可能低于其它两者。

什么是水平触发?什么是边缘触发

  • 水平触发(LT,Level Trigger)模式下,只要一个文件描述符就绪,就会触发通知,如果用户程序没有一次性把数据读写完,下次还会通知;
  • 边缘触发(ET,Edge Trigger)模式下,当描述符从未就绪变为就绪时通知一次,之后不会再通知,直到再次从未就绪变为就绪(缓冲区从不可读/写变为可读/写)。
  • 区别:边缘触发效率更高,减少了被重复触发的次数,函数不会返回大量用户程序可能不需要的文件描述符。
    为什么边缘触发一定要用非阻塞(non-block)IO:避免由于一个描述符的阻塞读/阻塞写操作让处理其它描述符的任务出现饥饿状态。

有哪些常见的IO模型

  • 同步阻塞IO(Blocking IO):用户线程发起IO读/写操作之后,线程阻塞,直到可以开始处理数据;对CPU资源的利用率不够;
  • 同步非阻塞IO(Non-blocking IO):发起IO请求之后可以立即返回,如果没有就绪的数据,需要不断地发起IO请求直到数据就绪;不断重复请求消耗了大量的CPU资源;
  • IO多路复用: 让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作。
  • 异步IO(Asynchronous IO):用户线程发出IO请求之后,继续执行,由内核进行数据的读取并放在用户指定的缓冲区内,在IO完成之后通知用户线程直接使用。

你可能感兴趣的:(操作系统概念)