操作系统基础-第一篇:虚拟化

操作系统通过虚拟化技术来为进程提供独占CPU和内存的抽象。

CPU虚拟化

本部分通过说明对进程的基本认识、受限的直接执行机制以及进程的若干种调度策略来理解操作系统提供的CPU虚拟化。

进程

进程是一个正在被一个或多个线程执行的计算机程序。计算机程序是一个存储在磁盘文件中的指令集合,进程就是这些指令从磁盘加载到内存中之后的执行。进程的状态包括:执行、就绪和阻塞。进程是计算机中分配资源的最小单元。

根据进程的资源需求程度,可以把进程分为CPU密集型(数学计算应用)、I/O密集型(文件服务器、Web服务器)和内存密集型(内存数据库服务器)。

进程与线程都是操作系统的概念。其区别如下:

进程线程
进程是操作系统中资源分配的最小单元,每个进程一个地址空间。线程是操作系统中执行调度的最小单元。一般来说,一个CPU在一个时间只能执行一个线程。
进程之间具有隔离性。一个进程故障不会导致另一个进程故障。线程之间不具有隔离性,如果线程发生了SegmentFault这样的错误会导致该进程下的所有线程结束。
一个进程占用更多的资源。需要更多的时间来退出和创建。一个线程占用更少的资源。需要更少的时间来退出和创建。
进程间通信需要使用使用操作系统提供的IPC来完成。例如:套接字、共享内存、消息队列、信号等。线程间通信只需要通过共享数据来完成。因为其本身共享内存,所以通信简单。

协程并不是操作系统的概念。它是编程语言的特征,由编程语言的runtime来提供支持。例如Java的JVM提供的green thread、Go的Runtime提供的goroutine。协程简述来说就是轻量级线程,它们可以是在同一个OS线程上允许,也可以由其他OS线程运行。

机制:受限的直接执行

Key: 内核态/用户态,陷阱,上下文切换、时钟中断

操作系统需要尽可能地为进程提供更好的执行性能,也需要限制进程以防止进程执行非法操作。操作系统为此引入进程的用户/内核模式、陷阱表和时钟中断。

在用户模式下,进程只能执行受限制的操作。例如,进程不能执行IO操作等。在内核模式下,进程可以无限制地执行指令。进程要执行系统调用,必须在用户模式下通过调用陷阱指令陷入内核模式,然后操作系统为调用进程执行系统调用的工作,最后操作系统通过调用从陷阱中返回指令回到用户模式。

陷阱表是操作系统在boot时初始化的维护从陷阱类型到陷阱处理函数的映射。用以告诉操作系统在遇到某个异常时,操作系统如何处理该异常。

时钟中断会周期性地中断进程,操作系统预先设定的时钟中断处理程序会被执行。该机制用于操作系统重新获得控制权,通过保存和恢复进程的上下文,对进程进行调度。

策略:进程调度

关键词: 调度策略,衡量指标,结合I/O,多处理器调度

调度是把资源分配给任务的行为。在此处,调度就是把单个CPU资源分配给不同进程执行任务的活动。衡量调度策略的指标包括周转时间(turnaround time),响应时间(response time)。调度策略分为抢占式和协作式两种。

护航效应(convoy effect)是一些耗时较少的潜在资源消费者被排在重量级的资源消费者之后的问题。

先进先出(FIFO): 进程按照其创建顺序来执行。优点:容易实现。缺点:单个运行时间很长的进程在前面时,会造成后续短时间运行的进程也会有很长的周转时间。

最短任务优先(SJF): 先运行最短的任务,再运行次短的任务,如此重复下去。优点:在所有工作同时到达的前提下,是最优调度。缺点:需要所有工作同时到达并且预知每个工作的时间。

抢占式最短作业优先(PSJF): 向SJF中添加抢占,当新任务到达时,比较每个任务的完成时间,随后据此选择待运行的任务。解决了SJF需要所有工作同时到达的缺点。

轮转(RoundRobin): 轮转在一个时间片(time slice)内运行一个任务,然后切换到运行队列的下一个任务。优点:有很好的平均响应时间。缺点:平均周转时间差,有时甚至不如FIFO。

多级反馈队列(MLFQ, Multilevel Feedback Queue): 由多个具有不同优先级的独立队列组成,一个任务在同一时间只能处于一个队列中,优先度高的队列总是被先运行。具体的算法见[Wiki-Multilevel Feedback Queue](Multilevel feedback queue - Wikipedia) 。该策略平衡了响应时间和周转时间,并且能够解决饥饿和愚弄问题。

比例份额(Proportional-Share): 每个任务都有一定的资源使用比例,操作系统结合该信息来调度任务。具体的策略包括彩票调度(lottery scheduling)和步长调度(stride scheduling)。比例份额调度有两个问题使得其不流行,1)不能很好地适应IO;2)确定每个进程的比例是很难的。

多处理器调度(Multiprocecssor Scheduling): 在多个CPU上调度工作。需要考虑到缓存一致性、缓存亲和性和并发控制。有单队列多处理器调度和多队列多处理器调度两种方式。前者简单但缺乏可扩展性、具有较差的缓存亲和性;后者具有可扩展性和不错的缓存亲和性,但难以做到负载均衡与可扩展性、缓存亲和性之间的权衡。

结合I/O使用重叠技术,可以提高系统整体的资源利用率。具体来说就是,在一个进程因为执行I/O操作而阻塞时,操作系统可以切换至另一个处于就绪状态的进程。


内存虚拟化

关键词:虚拟内存、地址转换、空闲空间管理、分页、TLB、交换空间

下图展示的是一个Linux进程内存布局的图示。

虚拟内存是操作系统用于给用户提供一个很大内存的假象的内存管理技术。其主要目标包括透明、保护和高效。虚拟内存的实现技术之一是地址转换(address translation),利用地址转换,硬件对每次内存访问进行处理,将指令中的虚拟地址转换为数据实际存储的物理地址。

空闲空间管理是操作系统管理进程堆空间的技术。通过合并与分割空闲链表中的节点,操作系统完成对进程堆空间的分配请求。初始时,进程有一个较小的堆空间,随着后续进程向操作系统申请内存,堆会适当地通过sbrk增大。相关的分配策略包括:最有匹配、最差匹配、首次匹配和下次匹配等,更高级的策略如分离空闲列表、伙伴系统以及高级的数据结构平衡树等也用于管理空闲空间。

当用户进程申请大小为M的内存时,如果空闲链表中满足大小≥M的节点且M>M_MMAP_THRESHOLD(64位Linux机上是4KB),那么内存分配器不会通过sbrk增长堆来为其分配内存,而是通过调用mmap申请一个匿名隐私映射来为其分配内存。当用户进程通过free告知内存分配器标志该内存区域为未使用后,内存分配器并不会将该块内存返回给操作系统。

操作系统管理空间的方法有两种。一种是分段,另一种是分页。

在使用分段管理空间的操作系统中。操作系统为每一个进程提供一对/多对基址寄存器和界限寄存器,凭此为进程提供受限制的空间访问。但是一个很严重的问题就是很难处理堆中被释放的空间,从而导致内部碎片。另一个问题就是,空间被分为大小不同的段,存在外部碎片问题,而通过紧凑来解决该问题又会造成CPU资源浪费。

在使用分页管理空间的操作系统中。完成从虚拟内存地址到物理内存地址的映射是通过页表来实现的。并且通过使用多级页表,能够将页表的每个部分都放入一页中,从而减少内部碎片(设想一下,如果一个页表包含16页,那么即使是只有第一页和最后一页存在两个有效页表项,中间部分的未使用页也需要驻留在内存中。这减少了空间利用率。)。此外,在TLB硬件的帮助下,操作系统快速地完成从虚拟内存地址到物理内存地址的转换能够得以实现。操作系统为了给进程提供一个很大容量的进程地址空间,其在磁盘上留了一块空间作为交换空间。当物理内存中驻留的页超过一定阈值时,swap daemon会使用LRU这样的页替换策略将部分页换出到交换空间。在换出页的时候,操作系统需要考虑页的脏位等。为了解决抖动问题(系统中存在相当多的进程进行非常频繁的内存访问,这导致了大量的换入换出),有些系统使用了准入控制(admission control),该技术限制了存在的进程数量。目前一些操作系统会采用更严格的技术处理内存过载,比如某些Linux版本使用out-of-memory killer来杀死内存过于密集的进程。

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值