Skip to content

Latest commit

 

History

History
138 lines (112 loc) · 13.4 KB

[01]操作系统.md

File metadata and controls

138 lines (112 loc) · 13.4 KB

# 进程管理单元PCB(Process Control Block)

PCB用来描述和控制进程的运行的一个数据结构。 PCB是进程存在的唯一标志,系统能且只能通过PCB对进程进行控制和调度; PCB记录了操作系统所需的、用于描述进程的当前情况以及控制进程运行的全部信息;

# 进程的本质

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。

# 如何创建一个进程

  1. 通过Runtime.exec()方法来创建一个进程;
  2. 通过ProcessBuilder的start方法来创建进程;

# fork函数、 为什么fork函数会返回两次?

fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。 由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。 因此fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。

# 进程树是什么?

进程树是一种进程关系表示方法。由父进程和子进程两部分组成。

# 进程调度的算法

  • 先来先服务调度算法:每次从就绪队列选择最先进入队列的进程,然后一直运行,直到进程退出或被阻塞,才会继续从队列中选择第一个进程接着运行;
  • 最短作业优先调度算法:优先选择运行时间最短的进程来运行,这有助于提高系统的吞吐量;
  • 高响应比优先调度算法:每次进行进程调度时,先计算「响应比优先级」,然后把「响应比优先级」最高的进程投入运行;
  • 时间片轮转调度算法:每个进程被分配一个时间段,称为时间片(Quantum),即允许该进程在该时间段中运行;
  • 最高优先级调度算法:从就绪队列中选择最高优先级的进程进行运行;
  • 多级反馈队列调度算法:「多级」表示有多个队列,每个队列优先级从高到低,同时优先级越高时间片越短。「反馈」表示如果有新的进程加入优先级高的队列时,立刻停止当前正在运行的进程,转而去运行优先级高的队列;

# 进程死锁的四个必要条件?

  • 互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。
  • 不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。
  • 请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
  • 循环等待条件:在发生死锁时必然存在一个进程等待队列{P1,P2,…,Pn},其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路,环路中每一个进程所占有的资源同时被另一个申请,也就是前一个进程占有后一个进程所申请的资源。

# 检测进程死锁,写一个死锁示例

检查循环引用

# 预防死锁的方法

  • 破坏“请求和保持条件”条件:1.创建进程时,要求它申请所需的全部资源,系统或满足其所有要求,或什么也不给它。这是所谓的 “ 一次性分配”方案;2.要求每个进程提出新的资源申请前,释放它所占有的资源。这样,一个进程在需要资源S时,须先把它先前占有的资源R释放掉,然后才能提出对S的申请,即使它可能很快又要用到资源R;
  • 破坏“不可剥夺条件”条件:如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占有的资源,如果有必要,可再次请求这些资源和另外的资源;
  • 破坏“循环等待”条件:将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序(升序)提出;

# 哪些解锁方式?

  • 资源剥夺法。挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态;
  • 撤销进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行;
  • 进程回退法。让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点;

# 进程间通信的方式有哪些?

  1. 管道:管道由父进程创建,进程fork子进程之后,就可以在父子进程之间使用了;
  2. 命名管道
  3. 消息队列
  4. 信号量
  5. 共享内存
  6. socket

# 线程的数据结构

  • 栈(stack)
  • 上下文(context)

# 线程的本质

线程是指进程内的一个执行单元,也是进程内的可调度实体。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。

# 守护进程是什么?挂了怎么办?

守护进程是在后台运行不受终端控制的进程。可以使用双守护进程避免守护进程异常退出。

# 内存分页

线性地址是连续的,如果直接使用线性地址作为物理地址,那么为每个段分配的物理内存就必须是连续的物理内存。这不利用碎片化内存的利用,为内存管理增大了难度。所以引入了分页机制,将地址分为大小固定的页(一般为4096字节),按页为单位进行映射。连续的线性地址可以映射到不连续的的物理内存上。 分页的另一个优点是,当物理内存不足时,可以按页为单位将内存的内容转换到磁盘上保存起来。 如果不使用分页,则只能整个段整个段的进行转换。

# 页中断

当 CPU 访问的页面不在物理内存时,便会产生一个缺页中断,请求操作系统将所缺页调入到物理内存。

# 页调度算法

当出现缺页异常,需调入新页面而内存已满时,选择被置换的物理页面。

  • 最佳页面置换算法(实际系统中无法实现):置换在「未来」最长时间不访问的页面;
  • 先进先出调度算法:根据页面进入内存的时间先后选择淘汰页面,先进入内存的页面先淘汰,后进入内存的后淘汰;
  • 最近最少调度算法:选择淘汰页面时会考虑页面最近的使用,选择最长时间没有被访问的页面进行置换;
  • 最近最不常用调度算法:总是根据一段时间内页面的访问次数来选择淘汰页面,每次淘汰访问次数最少的页面;

# 什么是虚拟内存,为什么需要虚拟内存

电脑中所运行的程序均需经由内存执行,若执行的程序占用内存很大或很多,则会导致内存消耗殆尽。为解决该问题,虚拟内存技术匀出一部分硬盘空间来充当内存使用。当内存耗尽时,电脑就会自动调用硬盘来充当内存,以缓解内存的紧张。

# 虚拟内存和物理内存的映射方式

虚拟地址和物理地址的映射关系是以“页”为单位的。分页就是把整个虚拟内存和物理内存分割成大小固定的块,以一个页作为映射的最小单位。运行时,CPU请求一个虚拟地址,虚拟地址又被翻译为物理地址,从而确定数据在内存中的哪个位置。

# 线上cpu占比过高怎么排查?

  1. top命令确认占用CPU高的进程;
  2. top -H -p 进程号 ,查找占用CPU高的线程;
  3. jstack 进程号 | grep 线程ID;

# 如何查看线程的执行情况?

  • ps -T -p 1092
  • top -H -p 1092

# Linux的共享内存如何实现?

  1. mmap()系统调用:mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问;
  2. 系统V共享内存:系统V共享内存通过shmget获得或创建一个IPC共享内存区域,并返回相应的标识符。内核在保证shmget获得或创建一个共享内存区,初始化该共享内存区相应的shmid_kernel结构注同时,还将在特殊文件系统shm中,创建并打开一个同名文件,并在内存中建立起该文件的相应dentry及inode结构,新打开的文件不属于任何一个进程(任何进程都可以访问该共享内存区)。所有这一切都是系统调用shmget完成的。

# Linux 中的用户模式和内核模式是什么含意?

  • 当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。
  • 当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。

# Linux生成daemon进程是否要二次fork?

  • 调用第一次fork的作用:让shell认为这条命令已经终止,不用挂在终端输入上;为后面setsid服务,因为调用setsid函数的进程不能是进程组组长,如果不fork出子进程,则此时的父进程是进程组组长,就无法调用setsid。当子进程调用完setsid函数之后,子进程是会话组长也是进程组组长,并且脱离了控制终端,此时,不管控制终端如何操作,新的进程都不会收到一些信号使得进程退出;
  • 第二次fork的作用:虽然当前关闭了和终端的联系,但是后期可能会误操作打开了终端。但是只有会话首进程能打开终端设备,所以再fork一次,把父进程退出,再次fork的子进程作为守护进程继续运行,保证了该精灵进程不是对话期的首进程,第二次不是必须的,是可选的

# Linux命令,awk

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具

# md5长度是多少?

128位,以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。