前言
针对于本博客内容仅用于面试方面知识进行一个汇总,并不代表所有操作系统的内容。(说到底就是要面向面试学习了)
正文
操作系统基本名词
并行
并行是指同一时刻,能够执行多个线程或者进程。(并行需要多个CPU或者多个核心,让不同的进程或者线程在不同的位置执行)
并发
宏观上是指一个CPU或者一个核心能够执行多个进程或者线程,微观上是指在一个核心内通过调度算法(例如轮询,时间片)使得多个进程或者线程看起来像是同时进行。(实际上是切换速度太快了,但是实质上仍然是只能执行一个)
共享
共享是指系统内的资源可以被并发的进程公共所有。
共享分为:互斥共享和同步共享
互斥共享的资源成为临界资源,即不能被多个进程同时占有。
虚拟
虚拟是指让一个物理实体转换成多个逻辑实体。通俗点说就是让每一个服务进来后都感觉有一个专门的计算机为他工作。(典型例子:并发)
异步
异步是指进程不是一次性执行完毕,而是走走停停最后到达终点。
操作系统基本功能
进程管理
进程控制、进程同步、进程通信、死锁处理、处理机调度等。
内存管理
内存分配、地址映射、内存保护与共享、虚拟内存等。
文件管理
文件存储空间管理,目录管理,文件读写管理,文件保护等。
设备管理
缓冲管理,设备分配,设备处理,虚拟设备等。
系统调用
如果一个进程在用户态需要内核态的功能时,则该进程需要转换为内核态进行功能调用(由操作系统完成)。
进程管理
进程
进程是资源分配的基本单位,用来管理资源。
进程控制块(PCB)用来描述进程的基本信息和运行状态,所谓的创建进程和撤销进程都是对PCB进行操作。(PCB是描述进程的数据结构)
线程
线程是调度的基本单位,一个进程可以拥有多个线程,并且这些线程可以共享进程资源(这里也代表线程不拥有资源,只是用进程的资源)。
进程和线程的区别
1.资源方面
进程拥有资源,但是线程不拥有资源,只是使用创建自己的进程的资源。
2.调度方面
线程是调度的基本单位,同一进程内的线程切换不会导致进程切换,但是不同进程内的线程切换会导致进程切换。
3.开销方面
创建进程的开销大(创建或销毁进程需要给其分配和回收内存空间,I\O设备等),创建线程的开销相比较小。
4.通信方面
进程间通信需要使用进程同步和互斥手段用来保证数据一致性,但是同一进程内的线程通信只需要读写同一进程的数据段(统一进程资源一样)即可。
进程的状态和状态转换
进程主要有三个状态:
运行状态:指正在CPU中运行的进程。
就绪状态:指已经被唤醒,但需要等待正在运行的进程结束后才能尝试运行
等待状态:指休眠的进程,在没被唤醒前无法执行。
进程调度算法
1.先来先服务(FCFS)
按照作业请求的时间顺序依次执行。
特点:有利于长作业执行,不利于短作业执行。因为如果短作业比长作业后来的话,那么短作业则需要等待长作业执行完毕,十分消耗时间。
2.短作业优先
听名字就应该知道该算法是针对于短作业的,优先执行时间最短的作业。
特点:如果在就绪队列中存在多个短作业任务,那么长作业任务将最后执行。
3.最短剩余时间优先
针对于估计的剩余时间中挑选出最短的作业进行执行,和上述一样,针对长作业十分不友好。
4.时间片调度
就绪队列采用FCFS的方式将作业排成队列,每次调度,CPU将时间片分配给队首进程,当队首进程时间片用完后会进入就绪队列的尾部。
特点:如果时间片过短会导致进程切换十分频繁影响效率,如果时间片过长会导致进程切换太慢使得效率很低。
5.优先级调度
给每个进程分配一个优先级别,高优先级别先执行。
特点:优先级调度会使得低优先级进程执行十分靠后,所以可以根据时间的推移增加低优先级进程的级别。
6.多级反馈队列
实质上就是优先级调度和时间片调度的合体版。设置多个队列,每个队列能获得的时间片不同,将当前队列的进程执行完毕后移送只上一级别队列。(只有当上层队列没有进程时,才会执行下层进程)
进程同步
临界资源
指该资源被多个进程所需要(即需要该资源的进程无法同时执行)
临界区
对临界资源访问的代码块叫做临界区。
同步与互斥
同步:指多个进程可同一时刻一起执行。
互斥:指多个进程中同一时刻只能有一个进程可以执行。
信号量
用于解决进程同步问题的一个整型变量,具有P操作和V操作(P操作类似 + 1,V操作类似 - 1)。
当信号量 = 0 时,代表该进程无法访问临界区,需要进入等待队列(即等待信号量 > 0)
当信号量 > 0 时,代表该进程可以访问临界区,在访问前需要对信号量执行P操作,访问结束后执行V操作。
当信号量只能 = 0 或 1 时,就有点类似于Java的锁资源,只能允许一个进程访问,其他进程访问时需要等待。
死锁
当多个进程因为不正当占有导致多个进程进入无休止的等待。
死锁的预防
银行家算法(这里不做展开,只简单讲一下:相当于这个算法掌管着所有资源,当进程向银行家请求资源时候,如果进程所需要的资源不能够完全满足则不给它分配,如果满足则给它分配)
进程通信(IPC)
直接通信
直接在进程内调用send,receive进行发送和接收消息。
send(receiver,message)是给指定进程发送给消息(发送到进程的消息缓冲队列中)
receive(Sender,message)用于接收来自某进程的信息(从自己进程的消息缓冲队列接收信息)
特点:只有共享了消息队列的一对进程才能够建立通信链路(自动创建),
间接通信
1.管道(pipeline)
管道是一种特殊的文件,一般叫pipe文件,具有两个端口的通信管道,为半双工通信(即两方都可以进行数据发送和接收,但不能同时进行),并且只能够使用在具有血缘的进程中(像父子进程和兄弟进程),存在于内存中。
工作原理:在创建管道时候会创建两个文件修饰符:fd[0]和fd[1],fd[0]用于读操作,fd[1]用于写操作。
2.命名管道
是在相当于管道的去除只能使用于父子进程的条件。
3.消息队列
是消息的链接表,存放在内核中。一个消息队列由一个标识符(ID)确定。
特点:
1.消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。
2.消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
3.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
4.信号量
相当于是进程间的一把锁,用于解决进程访问同步资源的数据一致性问题。
5. 共享内存
允许多个进程访问的同一内存区域(因为访问的同一块内存区域,所以不需要拷贝内存,而是直接操作内存,效率十分高,是最快的IPC),但是多个线程访问同一资源时候需要考虑同步问题,所以一般共享内存和信号量一起使用。
6.套接字
用于不同机器的进程通信(可以参考Java的Socket)
7.信号
信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送 信号给进程本身。
内存管理
逻辑地址
逻辑地址也可以叫做相对地址,是相对于进程的物理地址进行的偏移。
物理地址
物理地址也可以叫做绝对地址,是在内存中真正的地址。
虚拟内存
虚拟内存的目的是为了让物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。
虚拟内存是指将程序所需要的数据加载进内存,不需要的数据先放置在外存,当需要的时候再通过外存加载到内存中。(这期间操作系统也需要对内存中不用的数据写回外存中),使得可以运行超过内存大小的程序。
分区存储
分区主要分为两种分配方式:固定内存分配 和 动态分区分配 ,分区是一种连续分配方式。
1.固定分区分配
将内存分为多个区域,每个区域只能给一个进程使用。
缺点:当进程所需内存空间远小于分区所具有的内存空间时候,就会造成极大的内存浪费。
2.动态分区分配
当进程申请内存空间时候,我们再根据(空闲内存链)空闲内存表进行分配内存,表中具有信息(分区号,分区空间,起始地址,状态)。当进程撤销时再更新空闲内存表。
缺点:可能会产生内存碎片(即空闲内存分区空间太小,无法被使用,当这种情况很多的时候就会浪费大量内存)
分页存储
分页的基本思想是:将内存分为多个小的内存区(也可以叫页框),再将申请空间的进程也分成适当的部分(也可以叫页面),再根据进程的部分进行分配空间。(即页表与页框一一对应)
内存管理单元(MMU):管理地址空间和物理内存转换。
页表:
页面置换算法
是指当操作系统分配给进程的物理块被页面占满时,需要进行的页面置换的算法。
1. 最佳置换
算法是将最久未被使用的页面进行替换,这样可以保证缺页率较低。
2.LRU(最近最久未使用)
算法是将最近最久未被使用的页面进行替换,使用LRU算法需要在内存中维护一个链表结构,每当使用一个页面时候,就将对应的页面放到链表头部,当出现缺页时,就取链表尾部(即最近最久未使用的页面)将其置换(因为需要额外维护链表 + 对链表进行更新,所以LRU算法开销很大)。
3.FIFO(先进先出)
这就是典型的队列式算法,当发生缺页时,选出年龄最大的页面(即最先进入物理物理块的页面)进行替换。
分段存储
进程的地址空间,会根据自身的逻辑关系划分为若干个段,每个段有个段名(从0开始)。
内存分配规则:以段为单位进行分配,每个段在内存中占据连续空间,但是段与段之间可不连续。
段表[段号,段长,基址(即物理地址,也是段的起始地址)]。