天天看点

操作系统读写者问题实验报告_操作系统知识点总结

用户态和内核态

用户态和内核态的区别?

明白这两个概念之前,我们得知道用户空间和内核空间。

用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等。

内核空间:是系统内核来操作的一块空间,这块空间里面存放系统内核的函数、接口等。

在用户空间下执行,我们把此时运行的程序的这种状态成为用户态,而当这段程序执行在内核的空间执行时,这种状态称为内核态。

当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核状态。此时处理器处于特权级最高的(0级)内核代码。当进程处于内核态时,执行的内核代码会使用当前的内核栈。每个进程都有自己的内核栈。

当进程在执行用户自己的代码时,则称其处于用户态。即此时处理器在特权级最低的用户代码中运行。当正在执行用户程序而突然中断时,此时用户程序也可以象征性地处于进程的内核态。因为中断处理程序将使用当前进程的内核态。

延伸阅读:内核态与用户态是操作系统的两种运行级别,跟intel cpu没有必然联系,intel cpu提供Ring0-Ring3三种级别运行模式,Ring0级别最高,Ring3级别最低。Linux使用了Ring3级别运行用户态。Ring0作为内核态,没有使用Ring1和Ring2.Ring3不能访问Ring0的地址空间,包括代码和数量。Linux进程的4GB空间,3G-4G这1G部分大家是共享的,是内核态的地址空间,这里存放在整个内核代码和所有的内核模块,以及内核所维护的数据。用户运行一程序,该程序所创建的进程开始是运行在用户态的,如果要执行文件操作,网络数据发送等操作,必须通过write,send等系统调用,这些系统会调用内核中的代码来完成操作,这时,必须切换到Ring0,然后进入1G的内核地址空间去执行这些代码完成操作,完成后,切换Ring3,回到用户态。这样,用户态的程序就不能随意操作内核地址空间,具有一定的安全保护作用。

用户态和内核态的转换

什么时候从用户态切换到内核态?

用户态切换到内核态的3种方式?

(1)系统调用

这是用户进程主动要求切换到内核态的一种方式,用户进程通过系统调用申请操作系统提供的服务程序完成工作。

而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,该中断是程序人员自己开发出的一种正常的异常,这个异常具体就是调用int $0x80的汇编指令,这条汇编指令将产生向量为0x80的编程异常。(软中断)

操作系统读写者问题实验报告_操作系统知识点总结

(2)异常

当CPU在执行运行在用户态的程序时,发现了某些事件不可知的异常,这是会触发由当前运行进程切换到处理此

异常的内核相关程序中,也就到了内核态,比如缺页异常(硬中断)。

(3)外围设备的中断

当外围设备完成用户请求的操作之后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条将要执行的指令,转而去执行中断信号的处理程序,如果先执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了有用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

进程和线程

什么是线程和进程?

进程是一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程,比如在Windows系统中,一个运行的xx.exe就是一个进程。

线程是进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。

进程与线程的区别

线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行

通信方面:线程间可以通过直接读写同一进程中的数据进行通信,但是进程通信需要借助

IPC

Java中的内存分配:一个进程中可以有多个线程, 多个线程共享进程的堆和方法区(JDKI · 8 之后的元空

间) 资源, 但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈。

总结:线程是进程划分成的更小的运行单位, 一个进程在其执行的过程中可以产生多个线程。线程和进

程最大的不同在于基本上各进程是独立的, 而各线程则不一定, 因为同一进程中的线程极有可能会相互

影响。线程执行开销小, 但不利于资源的管理和保护;而进程正相反。

孤儿进程和僵尸进程有什么区别?
  • 孤儿进程就是说一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被

    init

    进程(进程

    ID

    1

    的进程)所收养,并由

    init

    进程对它们完成状态收集工作。因为孤儿进程会被

    init

    进程收养,所以孤儿进程不会对系统造成危害。
  • 僵尸进程就是一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过

    wait()

    waitpid()

    获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用

    wait()

    waitpid()

    ,那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵尸进程。僵尸进程通过

    ps

    命令显示出来的状态为

    Z

    。系统所能使用的进程号是有限的,如果产生大量僵尸进程,可能会因为没有可用的进程号而导致系统不能产生新的进程。如果要消灭系统中大量的僵尸进程,只需要将其父进程杀死,此时僵尸进程就会变成孤儿进程,从而被

    init

    进程所收养,这样

    init

    进程就会释放所有的僵尸进程所占有的资源,从而结束僵尸进程。
什么是守护进程? 守护进程是运行在后台的一种特殊进程,它是独立于控制终端的,并周期性地执行某些任务。

线程有哪两种?

  • 用户级线程(

    user level thread

    ):对于这类线程,有关线程管理的所有工作都由应用程序完成,内核意识不到线程的存在。在应用程序启动后,操作系统分配给该程序一个进程号,以及其对应的内存空间等资源。应用程序通常先在一个线程中运行,该线程被成为主线程。在其运行的某个时刻,可以通过调用线程库中的函数创建一个在相同进程中运行的新线程。用户级线程的好处是非常高效,不需要进入内核空间,但并发效率不高。
  • 内核级线程(

    kernel level thread

    ):对于这类线程,有关线程管理的所有工作由内核完成,应用程序没有进行线程管理的代码,只能调用内核线程的接口。内核维护进程及其内部的每个线程,调度也由内核基于线程架构完成。内核级线程的好处是,内核可以将不同线程更好地分配到不同的CPU,以实现真正的并行计算。
事实上,在现代操作系统中,往往使用组合方式实现多线程,即线程创建完全在用户空间中完成,并且一个应用程序中的多个用户级线程被映射到一些内核级线程上,相当于是一种折中方案。

进程间通信的方式

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

线程间的同步方式

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

  1. 互斥量(Mutex) :采用互斥对象机制, 只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个, 所以可以保证公共资源不会被多个线程同时访问。比如Java 中的synchronized 关键词和各种Lock 都是这种机制。
  2. 信号量(semphares) :它允许同一时刻多个线程访问同一资源, 但是需要控制同一时刻访问此资源的最大线程数量
  3. 事件(Event) :Wait/Notify: 通过通知操作的方式来保持多线程同步, 还可以方便的实现多线程优先级的比较操

进程的调度算法

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

为了确定首先执行哪个进程以及最后执行哪个进程以实现最大CPU 利用率, 计算机科学家已经定义了

一些算法, 它们是,

  • 先到先服务( FCFS ) 调度算法:从就绪队列中选择一个最先进入该队列的进程为之分配资源, 使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU 时再重新调度。
    • 非抢占式的调度算法,按照请求的顺序进行调度。
    • 有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。
    • I/O

      密集型进程也不利,因为这种进程每次进行

      I/O

      操作之后又得重新排队。
  • 短作业优先( SJF ) 的调度算法:从就绪队列中选出一个估计运行时间最短的进程为之分配资源,使它立即执行并一直执行到完成或发生某事件而被阻塞放弃占用CPU 时再重新调度。
    • 非抢占式的调度算法,按估计运行时间最短的顺序进行调度。
    • 长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。
  • 时间片轮转调度算法:时间片轮转调度是一种最古老, 最简单, 最公平且使用最广的算法, 又称RR(Round robin) 调度。每个进程被分配一个时间段, 称作它的时间片, 即该进程允许运行的时间。当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送往就绪队列的末尾,同时继续把

    CPU

    时间分配给队首的进程。
    • 时间片轮转算法的效率和时间片的大小有很大关系:
    • 因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。
    • 而如果时间片过长,那么实时性就不能得到保证。
  • 多级反馈队列调度算法:前面介绍的几种进程调度的算法都有一定的局限性。如短进程优先的调度算法, 仅照顾了短进程而忽略了长进程。多级反馈队列调度算法既能使高优先级的作业得到响应又能使短作业( 进程) 迅速完成。因而它是目前被公认的一种较好的进程调度算法,UNIX 操作系统采取的便是这种调度算法。
  • 优先级调度· 为每个流程分配优先级, 首先执行具有最高优先级的进程, 依此类推。具有相同优先级的进程以FCFS 方式执行。可以根据内存要求, 时间要求或任何其他资源要求来确定优先级。

大内核和微内核的区别

  • 大内核,就是将操作系统的全部功能都放进内核里面,包括调度、文件系统、网络、设备驱动器、存储管理等等,组成一个紧密连接整体。大内核的优点就是效率高,但是很难定位

    bug

    ,拓展性比较差,每次需要增加新的功能,都要将新的代码和原来的内核代码重新编译。
  • 微内核与单体内核不同,微内核只是将操作中最核心的功能加入内核,包括

    IPC

    、地址空间分配和基本的调度,这些东西都在内核态运行,其他功能作为模块被内核调用,并且是在用户空间运行。微内核比较好维护和拓展,但是效率可能不高,因为需要频繁地在内核态和用户态之间切换。

分时系统和实时系统的区别

  • 分时系统(

    Sharing time system

    )就是系统把

    CPU

    时间分成很短的时间片,轮流地分配给多个作业。它的优点就是对多个用户的多个作业都能保证足够快的响应时间,并且有效提高了资源的利用率。
  • 实时系统(

    Real-time system

    )是系统对外部输入的信息,能够在规定的时间内(截止期限)处理完毕并做出反应。它的优点是能够集中地及时地处理并作出反应,高可靠性,安全性。
  • 通常计算机采用的是分时,就是多个进程/用户之间共享

    CPU

    ,从形势上实现多任务。各个用户/进程之间的调度并非精准度特别高,如果一个进程被锁住,可以给它分配更多的时间。而实时操作系统则不同,软件和硬件必须遵从严格的时间限制,超过时限的进程可能直接被终止。在这样的操作系统中,每次加锁都需要仔细考虑。

静态链接和动态链接的区别

  • 静态链接就是在编译期间,由编译器和连接器将静态库集成到应用程序内,并制作成目标文件以及可以独立运作的可执行文件。静态库一般是一些外部函数与变量的集合。
  • 静态库很方便,但是如果我们只是想用库中的某一个函数,却仍然得把所有的内容都链接进去。一个更现代的方法是使用共享库,避免了在文件中静态库的大量重复。
  • 动态链接可以在首次载入的时候执行,也可以在程序开始执行的时候完成。这个是由动态链接器完成,比方标准

    C

    库(

    libc.so

    ) 通常就是动态链接的,这样所有的程序可以共享同一个库,而不用分别进行封装。

进程有哪些状态

操作系统读写者问题实验报告_操作系统知识点总结
  • 在五状态模型里面,进程一共有

    5

    中状态,分别是创建、就绪、运行、终止、阻塞。
  • 运行状态就是进程正在

    CPU

    上运行。在单处理机环境下,每一时刻最多只有一个进程处于运行状态。
  • 就绪状态就是说进程已处于准备运行的状态,即进程获得了除

    CPU

    之外的一切所需资源,一旦得到

    CPU

    即可运行。
  • 阻塞状态就是进程正在等待某一事件而暂停运行,比如等待某资源为可用或等待

    I/O

    完成。即使

    CPU

    空闲,该进程也不能运行。

运行态→阻塞态:往往是由于等待外设,等待主存等资源分配或等待人工干预而引起的。

阻塞态→就绪态:则是等待的条件已满足,只需分配到处理器后就能运行。

运行态→就绪态:不是由于自身原因,而是由外界原因使运行状态的进程让出处理器,这时候就变成就绪态。例如时间片用完,或有更高优先级的进程来抢占处理器等。

就绪态→运行态:系统按某种策略选中就绪队列中的一个进程占用处理器,此时就变成了运行态。

什么是上下文切换

对于单核单线程

CPU

而言,在某一时刻只能执行一条

CPU

指令。上下文切换(

Context Switch

)是一种将

CPU

资源从一个进程分配给另一个进程的机制。从用户角度看,计算机能够并行运行多个进程,这恰恰是操作系统通过快速上下文切换造成的结果。在切换的过程中,操作系统需要先存储当前进程的状态(包括内存空间的指针,当前执行完的指令等等),再读入下一个进程的状态,然后执行此进程。

什么是死锁

在两个或多个并发进程中,如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么该进程集合就产生了死锁。

死锁产生有哪些条件

死锁产生的根本原因是多个进程竞争资源时,进程的推进顺序出现不正确。

  • 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
  • 占有和等待:已经得到了某个资源的进程可以再请求新的资源。
  • 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显式地释放。
  • 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。

怎么解决死锁

对于死锁,主要有

4

种解决策略。

鸵鸟策略

就是直接忽略死锁。就像鸵鸟遇到危险的时候,把头埋在沙子里,假装根本没发生问题。因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能。当发生死锁时不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。大多数操作系统,包括

Unix

Linux

Windows

,处理死锁问题的办法仅仅是忽略它。

死锁预防

死锁预防是指通过破坏死锁产生的四个必要条件中的一个或多个,以避免发生死锁。

  • 破坏互斥:不让资源被一个进程独占,可通过假脱机技术允许多个进程同时访问资源;
  • 破坏占有和等待:有两种方案,
    • 已拥有资源的进程不能再去请求其他资源。一种实现方法是要求进程在开始执行前请求需要的所有资源。
    • 要求进程请求资源时,先暂时释放其当前拥有的所有资源,再尝试一次获取所需的全部资源。
  • 破坏不可抢占:有些资源可以通过虚拟化方式实现可抢占;
  • 破坏循环等待:有两种方案:
    • 一种方法是保证每个进程在任何时刻只能占用一个资源,如果要请求另一个资源,必须先释放第一个资源;
    • 另一种方法是将所有资源进行统一编号,进程可以在任何时刻请求资源,但要求进程必须按照顺序请求资源。

死锁避免

为了避免因为预防死锁而导致所有线程变慢,死锁避免采用了与死锁预防相反的措施。它允许三个必要条件,但通过算法判断资源请求是否可能导致循环等待的形成并相应决策,来避免死锁点的产生。因此,其前提是知道当前资源使用的整体情况,以及申请资源线程本身所占有的资源细节。

判断和决策中,主要使用两种避免方法。

  • 线程启动拒绝:如果一个线程的请求会引发死锁,则不允许其启动。
  • 资源分配拒绝:如果一个线程增加的资源请求会导致死锁,则不允许此申请。

整体来看,死锁避免是从资源和线程相互间关系着手,避免形成循环等待是其主要任务。

死锁检测和恢复

可以允许系统进入死锁状态,但会维护一个系统的资源分配图,定期调用死锁检测算法来检测途中是否存在死锁,检测到死锁发生后,采取死锁恢复算法进行恢复。

死锁检测方法如下:

  • 在资源分配图中,找到不会阻塞又不独立的进程结点,使该进程获得其所需资源并运行,运行完毕后,再释放其所占有的全部资源。也就是消去该进程结点的请求边和分配边。
  • 使用上面的算法进行一系列简化,若能消去所有边,则表示不会出现死锁,否则会出现死锁。

检测到死锁后,就需要解决死锁。目前操作系统中主要采用如下几种方法:

  • 取消所有死锁相关线程,简单粗暴,但也确实是最常用的
  • 把每个死锁线程回滚到某些检查点,然后重启
  • 连续取消死锁线程直到死锁解除,顺序基于特定最小代价原则
  • 连续抢占资源直到死锁解除

有哪些磁盘调度算法

先来先服务

  • 按照磁盘请求的顺序进行调度。
  • 优点是公平和简单。缺点也很明显,因为未对寻道做任何优化,使平均寻道时间可能较长。

最短寻道时间优先

  • 优先调度与当前磁头所在磁道距离最近的磁道。
  • 虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。一般来说,两端的磁道请求更容易出现饥饿现象。

电梯算法

  • 也叫

    SCAN

    扫描算法。电梯算法就是说读写磁头总是保持一个方向运行,直到该方向没有请求为止,然后改变运行方向。
  • 因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了最短寻道时间优先的饥饿问题。

什么是虚拟内存

虚拟内存就是说,让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。虚拟内存使用部分加载的技术,让一个进程或者资源的某些页面加载进内存,从而能够加载更多的进程,甚至能加载比内存大的进程,这样看起来好像内存变大了,这部分内存其实包含了磁盘或者硬盘,并且就叫做虚拟内存。

什么是分页系统

分页就是说,将磁盘或者硬盘分为大小固定的数据块,叫做页,然后内存也分为同样大小的块,叫做页框。当进程执行的时候,会将磁盘的页载入内存的某些页框中,并且正在执行的进程如果发生缺页中断也会发生这个过程。页和页框都是由两个部分组成的,一个是页号或者页框号,一个是偏移量。分页一般是有硬件来完成的,每个页都对应一个页框,它们的对应关系存放在一个叫做页表的数据结构中,页号作为这个页表的索引,页框号作为页表的值。操作系统负责维护这个页表。

分页和分段有什区别

  • 分页对程序员是透明的,但是分段需要程序员显式划分每个段。
  • 分页的地址空间是一维地址空间,分段是二维的。
  • 页的大小不可变,段的大小可以动态改变。
  • 分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。

页面替换算法有哪些

在程序运行过程中,如果要访问的页面不在内存中,就发生缺页中断从而将该页调入内存中。此时如果内存已无空闲空间,系统必须从内存中调出一个页面到磁盘对换区中来腾出空间。

最佳算法

所选择的被换出的页面将是最长时间内不再被访问,通常可以保证获得最低的缺页率。这是一种理论上的算法,因为无法知道一个页面多长时间不再被访问。

先进先出

选择换出的页面是最先进入的页面。该算***将那些经常被访问的页面也被换出,从而使缺页率升高。

LRU

虽然无法知道将来要使用的页面情况,但是可以知道过去使用页面的情况。

LRU

将最近最久未使用的页面换出。为了实现 LRU,需要在内存中维护一个所有页面的链表。当一个页面被访问时,将这个页面移到链表表头。这样就能保证链表表尾的页面是最近最久未访问的。因为每次访问都需要更新链表,因此这种方式实现的

LRU

代价很高。

时钟算法

时钟算法使用环形链表将页面连接起来,再使用一个指针指向最老的页面。它将整个环形链表的每一个页面做一个标记,如果标记是

,那么暂时就不会被替换,然后时钟算法遍历整个环,遇到标记为

1

的就替换,否则将标记为

的标记为

1

Linux文件系统是怎么样的

Linux

文件系统里面有文件和目录,组成一个树状的结构,树的每一个叶子节点表示文件或者空目录。每个文件基本上都由两部分组成:

  • inode

    :一个文件占用一个

    inode

    ,记录文件的属性,同时记录此文件的内容所在的

    block

    编号;
  • block

    :记录文件的内容,文件太大时,会占用多个

    block

除此之外还包括:

  • superblock

    :记录文件系统的整体信息,包括

    inode

    block

    的总量、使用量、剩余量,以及文件系统的格式与相关信息等;
  • block bitmap

    :记录

    block

    是否被使用的位图。

当要读取一个文件的内容时,先在

inode

中查找文件内容所在的所有

block

,然后把所有

block

的内容读出来。

操作系统读写者问题实验报告_操作系统知识点总结

硬链接和软链接有什么区别

  • 硬链接就是在目录下创建一个条目,记录着文件名与

    inode

    编号,这个

    inode

    就是源文件的

    inode

    。删除任意一个条目,文件还是存在,只要引用数量不为 。但是硬链接有限制,它不能跨越文件系统,也不能对目录进行链接。
  • 符号链接文件保存着源文件所在的绝对路径,在读取时会定位到源文件上,可以理解为

    Windows

    的快捷方式。当源文件被删除了,链接文件就打不开了。因为记录的是路径,所以可以为目录建立符号链接。

常见的几种内存管理机制

操作系统的内存管理机制了解吗?内存管理有哪几种方式?

简单分为连续分配管理方式和非连续分配管理方式这两种。连续分配管理方式是指为一个用户程序分配

一个连续的内存空间, 常见的如块式管理。同样地, 非连续分配管理方式允许一个程序使用的内存分

布在离散或者说不相邻的内存中, 常见的如页式管理和段式管理。

  • 块式管理:远古时代的计算机操系统的内存管理方式。将内存分为几个固定大小的块, 每个块中只包含一个进程。如果程序运行需要内存的话, 操作系统就分配给它一块, 如果程序运行只需要很小的空间的话, 分配的这块内存很大一部分几乎被浪费了。这些在每个块中未被利用的空间, 我们称之为碎片。
  • 页式管理:把主存分为大小相等且固定的一页一页的形式, 页较小, 相对相比于块式管理的划分力度更大, 提高了内存利用率, 减少了碎片。页式管理通过页表对应逻辑地址和物理地址。
  • 段式管理:页式管理虽然提高了内存利用率, 但是页式管理其中的页实际并无任何实际意义。段式管理把主存分为一段段的, 每一段的空间又要比一页的空间小很多。但是, 最重要的是段是有实际意义的, 每个段定义了一组逻辑信息, 例如, 有主程序段MAIN 、子程序段× 、数据段D及栈段S 等。段式管理通过段表对应逻辑地址和物理地址。
  • 段页式管理机制:段页式管理机制结合了段式管理和页式管理的优点。简单来说段页式管理机制就是把主存先分成若干段, 每个段又分成若干页,也就是说段页式管理机制中段与段之间以及段的内部的都是离散的。
参考:https://blog.nowcoder.net/n/42ee220483414f37952ef71f604a7ff5

继续阅读