关于操作系统,你所不知道的事儿(一)

出品 | CSDN博客

大家好,我叫导游!很多读者抱怨计算操作系统的知识点比较复杂,没有太多耐心去阅读,但在面试中却经常遇到。所以,我在这里提供了我整理的操作系统常见问题解答!这篇文章总结了一些我认为比较重要的操作系统相关的问题,比如进程管理、内存管理、虚拟内存等等。

文章的形式是通过面试官和求职者之间最喜欢的对话形式发展起来的。另外,高德哥上大学的时候才学过操作系统,但基本都忘记了。为了写这篇文章,他阅读了很多相关的书籍和博客。如果文中有什么需要补充和改进的地方,可以在评论区指出。如果觉得内容不错,别忘了点击观看哦!

我个人认为把操作系统学好是很有用的。详情请看我昨天在星球上分享的一段话:

本文只是对操作系统中一些更重要的概念的概述。如果深入学习,建议老老实实读书。另外,本文很多内容参考了《现代操作系统》第3版一书,非常感谢。

操作系统基础

1.1 什么是操作系统?

‍采访者:我们先从一个简单的问题开始吧!什么是操作系统?

我:我通过以下四点来给大家介绍一下什么是操作系统!

操作系统(OS)是管理计算机硬件和软件资源的程序,是计算机系统的内核和基石;

操作系统本质上是在计算机上运行的软件程序;

操作系统为用户提供与系统交互的界面;

操作系统分为内核和外壳(我们可以将外壳理解为围绕内核的应用程序,内核是能够操作硬件的程序)。

再多说一句内核:内核负责管理系统的进程、内存、设备驱动、文件和网络系统等,决定了系统的性能和稳定性。它是应用程序和硬件之间的桥梁。

内核是操作系统背后黑匣子的核心。

1.2 系统调用

‍采访者:什么是系统调用?能不能详细解释一下。

我:在介绍系统调用之前,我们先来了解一下用户态和系统态。

根据进程访问资源的特点,我们可以将系统上进程的运行分为两个层次:

用户模式(user mode):运行在用户模式或可以直接读取用户程序数据的进程。

系统模式(内核模式):很容易理解,在系统模式下运行的进程或程序几乎可以不受限制地访问计算机的任何资源。

说完用户态和系统态,什么是系统调用?

我们运行的程序基本上都是在用户态下运行的。如果我们调用操作系统提供的系统级子功能呢?那么你需要一个系统调用!

也就是说,在我们运行的用户程序中,所有与系统级资源相关的操作(如文件管理、进程控制、内存管理等)都必须通过系统调用向操作系统提出服务请求,并操作系统为你做。

这些系统调用按照功能大致可以分为以下几类:

设备管理。完成设备请求或释放、设备启动等功能。

文件管理。完成文件的读、写、创建、删除等功能。

过程控制。完成进程的创建、取消、阻塞和唤醒等功能。

进程通信。完成进程间消息传递或信号传递等功能。

内存管理。完成内存分配、回收、获取作业占用内存区域大小和地址等功能。

进程和线程

2.1 进程和线程的区别

‍采访者:好的!我明白!那你再说一遍:进程和线程的区别。

我:好的!下图是Java内存区域。下面从JVM的角度来谈谈线程和进程的关系吧!

如果你对Java内存区(运行时数据区)不是很了解,可以看这篇文章:《可能是关于Java内存区最清晰的文章》

从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的堆和方法区(JDK1.8之后的元空间)资源,但是每个线程都有自己的程序计数器,虚拟机堆栈和本机方法堆栈。

摘要:线程是一个进程被划分成的一个较小的运行单元。一个进程在其执行过程中可以产生多个线程。线程和进程最大的区别在于,基本上每个进程都是独立的,而每个线程却不一定,因为同一个进程中的线程很可能会相互影响。线程执行开销小,但不利于资源管理和保护;而过程正好相反。

2.2 进程的状态是什么?

‍采访者:那这个过程的状态是什么?

我:我们一般把进程分为5个状态,跟线程很像!

创建状态(新):进程正在创建中,尚未达到就绪状态。

就绪状态(ready):进程处于ready-to-run状态,即进程已经获得了除处理器之外的所有需要​​的资源,一旦处理器资源(处理器分配的时间片)达到就可以运行获得。

运行状态(running):进程在处理器上运行(单核CPU下任何时候只有一个进程在运行)。

阻塞状态(waiting):也称为等待状态,进程在等待一个事件并暂停操作,例如等待某个资源可用或等待一个IO操作完成。即使处理器处于空闲状态,该进程也无法运行。

已终止:进程正在从系统中消失。可能是进程正常结束或因其他原因被中断而退出运行。

2.3 进程间通信

‍采访者:进程间常用的通信方式有哪些?

我:大约有 7 种常见的进程间通信方式。

以下部分总结参考:《InterProcess Communication IPC(InterProcess Communication)》这篇文章推荐阅读,总结的很好。

管道/匿名管道(Pipes):用于具有亲和性的父子进程之间或兄弟进程之间的通信。

名称管道:匿名管道只能用于亲属关系的进程间通信,因为它们没有名称。为了克服这个缺点,提出了命名管道。知名管道严格遵循先进先出。命名管道以磁盘文件的形式存在,可以实现本机任意两个进程之间的通信。

信号(Signal):信号是一种比较复杂的通信方式,用于通知接收进程有事件发生;

消息队列:消息队列是以特定格式存储在内存中并由消息队列标识符标识的消息的链表。管道和消息队列的通信数据是先进先出的。与管道不同(未命名管道:文件只存在于内存中;命名管道:存在于实际的磁盘介质或文件系统中),消息队列存储在内核中,并且只有在内核重新启动(即操作系统重新启动)或显示时一个消息队列被删除,消息队列实际上被删除了。消息队列可以实现消息的随机查询。消息不必按照先进先出的顺序阅读,也可以根据消息的类型来阅读。它比先进先出更有优势。消息队列克服了信号携带信息量少的缺点,

信号量:信号量是多进程访问共享数据的计数器。信号量的目的是在进程之间进行同步。这种类型的通信主要用于解决与同步相关的问题并避免竞争条件。

共享内存:允许多个进程访问同一个内存空间,不同进程可以及时看到其他进程共享内存中数据的更新。这种方法需要某种同步操作,例如互斥量和信号量。可以说这是在进程之间进行通信的最有用的方式。

Sockets:此方法主要用于客户端和服务器之间通过网络进行通信。Socket是支持TCP/IP的网络通信的基本操作单元。它可以看作是不同主机之间进程之间双向通信的端点。相关功能完成通讯过程。

2.4 线程间同步的方式

‍采访者:线程间同步的方法有哪些?

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

互斥:使用互斥对象机制线程标识符 有什么用,只有拥有互斥对象的线程才有权访问公共资源。因为只有一个互斥对象,所以保证公共资源不会被多个线程同时访问。比如Java中的synchronized关键字和各种Locks都是这样的机制。

信号量(Semaphore):它允许多个线程同时访问同一个资源,但需要控制同时访问该资源的最大线程数。

事件(Event):Wait/Notify:可以通过通知操作保持多线程同步,也可以方便的实现多线程优先级比较操作。

2.5 进程调度算法

‍采访者:你知道操作系统中进程的调度算法有哪些吗?

我:嗯!这是我们在大学时学到的一个非常重要的知识点!

为了确定首先执行哪个进程以及最后执行哪个进程以实现最大 CPU 利用率,计算机科学家定义了一些算法,它们是:

操作系统内存管理基础

3.1 内存管理简介

‍采访者:操作系统的内存管理主要是做什么的?

我:操作系统的内存管理主要负责内存的分配和回收(malloc函数:申请内存,free函数:释放内存)。另外,地址转换就是将逻辑地址转换成对应的物理地址,其他功能也是由操作系统的内存管理来完成的。事物。

3.2 几种常见的内存管理机制

‍采访者:你了解操作系统的内存管理机制吗?内存管理有哪些类型?

我:我在学习操作系统的时候就知道了这个。

简单地分为两种:连续分配管理和非连续分配管理。连续分配管理是指为用户程序分配连续的内存空间,例如块管理。类似地,非连续分配管理允许程序使用的内存分布在离散或非连续内存中,例如页管理和段管理。

块管理:古代计算机操作系统的内存管理方式。将内存划分为固定大小的块,每个块只包含一个进程。如果程序需要内存来运行线程标识符 有什么用,操作系统会为其分配一个块。如果程序只需要很小的空间来运行,那么分配的大部分内存几乎都被浪费了。每个块中这些未使用的空间称为片段。

基于页面的管理:主内存被分成大小相等且固定的页面。页面更小,分割比基于块的管理更强,提高了内存利用率,减少了碎片。基于页的管理通过页表对应于逻辑地址和物理地址。

段管理:虽然页管理提高了内存利用率,但页的页管理实际上并没有任何实际意义。段管理将主存划分为段,每个段的空间远小于一个页的空间。但是,最重要的是段具有实际意义,每个段定义了一组逻辑信息,例如,有主程序段MAIN、子程序段X、数据段D和堆栈段S等。段管理通过段表对应逻辑地址和物理地址。

‍采访者:答案还不错!但是,一个非常重要的段页面管理机制被遗漏了。段页管理机制结合了段管理和页管理的优点。简单来说,segment-page管理机制就是先把主存分成几个segment,每个segment又分成几个page,也就是说segment-page管理机制是在segment之间和segment内是离散的。

我:谢谢面试官!我只是忘记了这个…

3.3 快速表和多级页表

‍采访者:页表管理机制中有两个非常重要的概念:快速表和多级页表。这两件事分别解决了页表管理中的两个重要问题。请给我简单介绍一下!

我:在分页内存管理中,有两点很重要:

虚拟地址到物理地址的转换更快。

解决虚拟地址空间大、页表大的问题。

快速观看

为了解决虚拟地址到物理地址的转换速度问题,操作系统引入了基于页表方案的快速表,以加快虚拟地址到物理地址的转换。我们可以将块表理解为一种特殊的高速缓存(Cache),其内容是页表的一部分或全部。作为页表的Cache,其作用与页表类似,但提高了访问率。因为页表是用来进行地址转换的,所以CPU在读写内存数据的时候需要访问主存两次。有了fast table,有时只访问一个cache memory,一个main memory,这样可以加快查找速度,提高指令执行速度。

使用快速表后的地址转换过程如下:

根据虚拟地址中的页码查找快速表;

如果页面在快速表中,则直接从快速表中读取对应的物理地址;

如果该页不在快速表中,则访问内存中的页表,从页表中获取物理地址,并将页表中的映射表项添加到快速表中;

当fast table满了,需要注册一个新的page时,按照一定的淘汰策略淘汰fast table中的一个page。

看完之后你会发现fast table和我们开发的系统中通常使用的缓存(比如Redis)非常相似。确实如此。操作系统中的很多思想,很多经典算法,都可以用在我们的日常生活中。在用于开发的各种工具或框架中找到它们的影子。

多级页表

引入多级页表的主要目的是避免将所有页表都保存在内存中而占用过多的空间,尤其是那些根本不需要的页表不需要保存在内存中。多级页表是时变空间的典型场景。详情请参考以下文章

多级页表如何节省内存:多级页表如何节省内存.html

总结

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

3.4 分页与分段的异同

‍采访者:分页机制和分段机制有什么异同?

一世:

共同点:

分页机制和分段机制都是为了提高内存利用率和减少内存碎片而设计的。

页面和段是离散存储的,因此两者都是离散分配内存的方式。但是,每个页面和段内的内存是连续的。

区别:

页面的大小是固定的,由操作系统决定;段的大小不是固定的,取决于我们当前运行的程序。

分页只是为了满足操作系统内存管理的需要,而段是逻辑信息的单位,在程序中可以体现为代码段和数据段,更能满足用户的需求。

3.5 逻辑(虚拟)地址和物理地址

‍采访者:您刚才提到了逻辑地址和物理地址的概念。我不太确定。你能给我解释一下吗?

我:嗯……好吧!我们的编程一般只能处理逻辑地址。例如,在C语言中,指针中存储的值可以理解为内存中的一个地址。这个地址就是我们所说的逻辑地址,逻辑地址是由操作系统决定的。物理地址是指实际物理内存中的地址,更具体地说,是内存地址寄存器中的地址。物理地址是内存单元的真实地址。

3.6 你了解 CPU 寻址吗?为什么需要虚拟地址空间?

‍采访者:你了解CPU寻址吗?为什么需要虚拟地址空间?

我:我真的不确定这部分!

所以面试完之后,我就默默的去查阅了相关文件!没有技术的眼泪被抛在脑后。

这部分内容参考了微软官网的介绍,地址:(v=vs.85).aspx

现代处理器使用一种称为虚拟寻址的寻址形式。使用虚拟寻址,CPU 需要将虚拟地址转换为物理地址才能访问真实的物理内存。真正完成虚拟地址到物理地址转换的硬件是CPU包含一个称为内存管理单元(MMU)的硬件。如下所示:

为什么要有虚拟地址空间?

让我们从没有虚拟地址空间的时候开始吧!当没有虚拟地址空间时,程序直接访问和操作物理内存。但这有什么问题呢?

用户程序可以访问任意内存,寻址内存的每个字节,这很容易(有意或无意地)损坏操作系统,导致操作系统崩溃。

同时运行多个程序特别困难。比如你想同时运行一个微信和一个QQ音乐,是不行的。为什么?举个简单的例子:微信在操作过程中给内存地址1xxx赋值后,QQ音乐也给内存地址1xxx赋值,那么QQ音乐给内存的赋值会覆盖之前微信赋值的值,即导致微信程序会崩溃。

综上所述:直接暴露物理地址会导致严重的问题,比如可能对操作系统造成损害,同时运行多个程序的困难。

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

虚拟内存

4.1 什么是虚拟内存?

‍采访者:还有一个常识性的问题!什么是虚拟内存?

我:这在我们平时使用电脑的时候很常见,尤其是Windows系统。很多时候我们使用了很多占用内存的软件,而这些软件占用的内存可能已经远远超过了我们电脑本身的物理内存。为什么这可能?正是因为虚拟内存的存在,通过虚拟内存,程序才能拥有超过系统物理内存大小的可用内存空间。此外,虚拟内存为每个进程提供了一致的、私有的地址空间,这让每个进程产生了自己对主存具有独占访问权的错觉(每个进程都有一个连续完整的内存空间)。这将更有效地管理内存并减少错误。

虚拟内存是计算机系统内存管理的一种技术,我们可以手动设置我们计算机的虚拟内存。不要只把虚拟内存想成是一种“利用硬盘空间扩充内存”的技术。虚拟内存的意义在于它定义了一个连续的虚拟地址空间,并将内存扩展到硬盘空间。推荐阅读:《关于虚拟内存的事》

维基百科中有几句话是这样描述虚拟内存的。

虚拟内存:使应用程序认为它有连续的可用内存(一个连续的、完整的地址空间),而实际上它通常被划分为多个物理内存碎片,还有一些临时存储在外部磁盘存储上,在需要时进行数据交换. 使用虚拟内存技术的系统比没有虚拟内存技术的系统更容易编写大型程序并更有效地使用真实物理内存(如 RAM)。目前大多数操作系统都使用虚拟内存,比如Windows家族的“虚拟内存”;Linux的“交换空间”等。来自:虚拟内存

4.2 局部性原则

‍采访者:要更好地理解虚拟内存技术,你必须知道计算机中众所周知的局部性原理。此外,局部性原则适用于程序结构和数据结构,这是一个非常重要的概念。

我:局部性原理是虚拟内存技术的基础。正是由于程序运行的局部性原则,才可以将程序的一部分加载到内存中开始运行。

以下是计算机操作系统教程第 4 章“内存管理”的节选。

早在 1968 年就有人指出,我们的程序在执行时往往表现出局部性规律,也就是说,在很短的时间内,程序执行仅限于一小部分,程序访问的存储空间是也仅限于某个区域。

局部性原则体现在以下两个方面:

时间局部性:如果程序中的一条指令执行一次,该指令可能很快会再次执行;如果某些数据已被访问,则可能很快会再次访问该数据。时间局部性的一个典型原因是程序中存在大量循环操作。

空间局部性:程序一旦访问了一个存储单元,其附近的存储单元也会在不久之后被访问,即一段时间内程序访问的地址可能集中在一定范围内,这是因为指令通常是顺序存储和执行,数据一般以向量、数组和表的形式存储在集群中。

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

4.3 虚拟内存

‍采访者:都说虚拟内存。你说的是虚拟内存!

一世:

本部分内容来自:网道考研操作系统知识点。

基于局部性原则,程序加载时,可以将程序的一部分加载到内存中,而将其他部分留在外部存储器中以启动程序执行。由于外部内存往往比内存大很多,所以我们运行的软件的内存大小实际上可以大于计算机系统的实际内存大小。在程序执行过程中,当访问的信息不在内存中时,操作系统会将需要的部分转移到内存中,然后继续执行程序。另一方面,操作系统将内存中暂时未使用的内容交换到外部内存,从而腾出空间来存储将要传输到内存中的信息。这样,

其实我觉得虚拟内存也是一种时间换空间的策略。你用CPU的计算时间和调用page in和out的时间,换取虚拟更大的空间来支持程序的运行。不得不感叹,编程世界几乎不是时间换空间,也不是空间换时间。

4.4 虚拟内存的技术实现

‍采访者:虚拟内存技术的实现情况如何?

我:虚拟内存的实现需要基于内存管理的离散分配。实现虚拟内存的三种方式:

按需分页存储管理:在分页管理的基础上,为了支持虚拟内存功能,增加了按需分页功能和页面替换功能。按需分页是目前最常用的实现虚拟内存的方法。在需求分页存储管理系统中,在作业开始运行之前,只加载要执行的段的一部分,并且可以运行。如果在作业运行过程中发现要访问的页面不在内存中,处理器会通知操作系统根据相应的页面替换算法将相应的页面转移到主存中,操作系统可以还将暂时未使用的页面替换到主存储器。在外部存储中。

请求段存储管理:在段存储管理的基础上,增加了请求段调整和段替换的功能。请求段存储管理方式与请求分页存储管理方式相同。在作业开始运行之前,只能加载当前段中要执行的部分并运行;在执行过程中,可以通过请求调用中断来动态加载要访问的访问。但程序段不在内存中;当内存空间已满,需要加载新的segment时,根据replacement函数适当调出segment,释放空间,加载新的segment。

请求段页面存储管理

在这里多说?很多人很容易混淆请求分页和分页存储管理。两者有什么区别?

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

它们之间的根本区别在于是否将作业的整个地址空间同时加载到主存中。按需分页内存管理不需要将作业的整个地址空间同时加载到主内存中。基于此,请求分页存储管理可以提供虚拟存储,但分页存储管理不能提供虚拟存储。

不管上面的实现,我们一般都需要:

一定的内存和外存:加载程序时,只需要将程序的一部分加载到内存中,其他部分留在外存中,然后程序才能执行;

页错误中断:如果要执行的指令或访问的数据还没有在内存中(称为页错误或段错误),处理器会通知操作系统将相应的页或段转移到内存中,然后继续执行程序;

虚拟地址空间:逻辑地址到物理地址的转换。

4.5 页替换算法

‍采访者:虚拟内存管理中一个很重要的概念就是页面替换算法。那你能谈谈页面替换算法的作用吗?常见的页面替换算法有哪些?

一世:

这道题经常以笔试题的形式出现,网上已经给出了很好的答案。我只是在这里总结一下。

在地址映射过程中,如果要访问的页在内存中没有的页中,就会发生缺页中断。

缺页中断是指要访问的页面不在主存中,操作系统需要先将其转移到主存中才能访问。此时,内存映射文件实际上变成了分页文件。

当页面错误发生时,如果当前内存中没有空闲页面,操作系统必须在内存中选择一个页面并将其移出内存,以便为要加载的页面腾出空间。用于选择淘汰哪个页面的规则称为页面替换算法,我们可以将页面替换算法看成是排除页面的规则。

参考:

《计算机操作系统——唐小丹》第四版

《理解计算机系统》

I/O 内存管理单元

快递/19781679

网道考研操作系统知识点整理:

版权声明:本文为CSDN博主“导哥”原创文章,遵循CC4.0 BY-SA版权协议。转载请附上原文出处链接和本声明。

原文链接:

☞阿里巴巴云将增资2000亿元,新基建再“走出去”!

☞ 看似无关紧要,哲学和机器学习有这么大的交集?

☞文科出身淘汰Instagram,被小扎“挤”走,建新冠追踪网站。这个程序员有点天才!

☞ 为了降低预测过程的计算成本,这些NLP模型压缩方法应该知道

☞这些常见的分布式存储系统你都知道吗?

☞京东智联云原生实践告诉你什么是监控日志的黄金法则

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论