操作系统 part1

实验好多,人好累...

一、进程和线程

references:
进程三种基本状态

进程和线程的概念、区别和联系
进程和线程的主要区别(总结)
进程间通信IPC

1、进程

进程,是资源分配和调度的基本单位,是对程序的封装(程序的一次执行),每个进程都有自己独立的地址空间,建立数据表维护代码段、堆栈段、数据段,所以创建进程开销较大。进程由程序段、数据段和PCB(进程控制块,包含pid、状态、优先级等等)组成。

1.1、进程状态:

就绪、执行、阻塞

1.2、通信方式:

  1. 管道(pipe):管道是半双工,数据只能单方向流动。管道是一个循环的内核缓冲区,管道一端进程顺序写入数据,另一端进程顺序读出。存在于内存。
    基于fork实现,故只适用于亲缘进程之间。
  2. 命名管道(FIFO/named PIPE):命名管道提供了一个路径名,名字存放于文件系统,内容存放于内存,只要能访问路径名就能建立通信,这样没有亲缘的进程也能使用管道通信。当一个进程以读的方式打开文件,一个进程以写的方式打开文件,那么就会建立管道。
    严格按照FIFO读写,写进末尾,从头读出。
    命名管道阻塞问题,不想阻塞可以试试读写模式。
  3. 消息队列(message queue):消息队列是存放在内核的消息链表,每个消息队列有一个标识符。
    消息队列存放在内核,独立于收发进程(所以进程结束了但是操作系统没重启,消息队列就还存在)。
    可以按照一定规则向消息队列写入信息,而管道只能写入无格式字节流
    消息能随机查询,不一定FIFO,可按消息类型读取。
  4. 信号(signal):信号是一种比较复杂的通信方式,用来通知接受进程某个事件已经发生(阻塞时等到激活再传递,未执行就保存到内核等到执行时传递)。
    用于通知进程某个事件已经发生。
  5. 信号量(semaphore):是一个计数器,可以用来控制多个进程对共享资源的访问,可以控制数量。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。控制多
    基于PV操作。
  6. 共享内存(share memory):多个进程可以直接读写同一块内存空间,需要依靠某种同步机制(信号量、互斥锁)来达到同步与互斥。
  7. 套接字(socket):可用于不同主机间通信。

1.3、进程的同步

  1. 临界区:临界区是指访问公用资源的程序片段(临界资源就是独占性的共享资源),它使得同一时间只能有一个线程进入临界区。当有线程进入临界区后,其他线程想访问就必须等待。
  2. 信号量:允许同一时间多个线程访问贡献资源,但是要控制最大线程数量。
  3. 互斥量:每个线程想要访问贡献资源,就要先加互斥锁,加了锁才能访问,操作结束后解锁。如果已经被加锁了,那么线程阻塞,等到解锁的时候会把阻塞的线程唤醒。
  4. 信号:通过通知保持多线程同步。

1.4、进程调度策略

  1. FCFS(先来先服务):队列实现,非抢占,先请求CPU的先分配。
  2. SJF(短作业优先):预估运行时间短的优先,需要知道预估的运行时间。
  3. 优先级调度算法:分为抢占式(运行时就绪队列出现优先级更高的就立即停止,把处理机分配给更高的)和非抢占式(一旦分配处理机就要执行完)。优先级高的先分配CPU。但是这个算法容易出现无穷阻塞或饥饿,即低优先级的进程可能一直阻塞(因为是静态优先级)。解决方法是老化,等待时间越长优先级变得越高(动态优先级)。
  4. 时间片轮转调度算法(RR):每个进程轮流获得一个时间片,允许进程执行一个时间片的时间。时间片设的过短,那么就在进程切换浪费了很多时间,效率低;时间片过长对短交互的响应过长。
  5. 多级反馈队列调度算法:设置多个就绪队列,并设置不同优先级,第1级优先级最高,优先级逐级递减。赋予每个就绪队列的时间片大小也不一样,优先级越高,时间片越小。每个进程进入内存后,先放到第1级队列,然后按照FCFS进行分配。如果第1级分配的时间片用完后还没执行完,就放到第2级,如此往下。并且,只有优先级高的就绪队列为空,才能分配时间片给优先级低的队列里的进程。并且是抢占式的,即出现更高优先级的就停下,分配给更高的。对于短作业能迅速完成,对于长作业能得到部分执行。

2、线程

线程,是进程的实际运作单位,是最小的执行和调度单位。线程的粒度比进程小。多个线程共享进程内的资源,使用同一地址空间,故创建线程开销小。
线程状态:就绪、执行、阻塞。

2.1、通信方式:

  1. 互斥锁:以排他方式防止数据结构被并发修改的方法。
  2. 读写锁:允许多个线程同时共享数据,而对写操作是互斥的。
  3. 信号量:和进程类似。
  4. 信号:和进程类似。

2.2、线程的同步

  1. 临界区:临界区是指访问公用资源的程序片段(临界资源就是独占性的共享资源),它使得同一时间只能有一个线程进入临界区。当有线程进入临界区后,其他线程想访问就必须等待。
  2. 信号量:允许同一时间多个线程访问贡献资源,但是要控制最大线程数量。
  3. 互斥量:每个线程想要访问贡献资源,就要先加互斥锁,加了锁才能访问,操作结束后解锁。如果已经被加锁了,那么线程阻塞,等到解锁的时候会把阻塞的线程唤醒。
  4. 信号:通过通知保持多线程同步。

3.进程和线程

3.1、区别:

  1. 进程是资源分配基本单位,线程是任务调度执行的基本单位。
  2. 进程拥有自己独立的地址空间,线程是共享。
  3. 进程创建撤销操作系统都要分配或回收资源(内存空间、IO设备等),开销大;线程只有少量寄存器和堆栈,开销较小。
  4. 进程实现了操作系统的并发,线程实现了进程内部的并发。

二、虚拟内存技术

references:
操作系统 虚拟内存技术

3.2、虚拟内存管理

1、概念

在程序装入时,将需要执行的部分装入内存,其余放在外存就可以启动程序执行。执行过程中,如果访问的信息不在内存中,就将需要的部分调入内存。另一方面,操作系统可以将暂时不用的部分调到外存。
虚拟内存的实现有以下三种方式:

  • 请求分页存储管理
  • 请求分段存储管理
  • 请求段页式存储管理

需要的硬件支持有:

  • 一定容量内存外存
  • 页表机制或者段表机制,作为主要数据结构
  • 中断机制
  • 地址变换机制,实现逻辑变换到物理地址的变换

2、请求分页、请求分段、请求段页式存储管理

2.1、 请求分页存储管理

页表字段:
页号、内存块号(该页面所放的内存块号)、页内地址(偏移量)、修改位(是否修改)、外存地址(此页在外存地址的位置)、状态位(该页是否调入内存)、访问字段(最近访问次数或最近访问时间)

当所要访问的页面不存在时,产生一个缺页中断,将所缺的页调入内存。
缺页中断步骤:缺页进程阻塞;如果内存中有空闲块,将页面调入该块,修改页表,如果没有,调用页面置换算法淘汰一个页面(修改过需写回外存);调页完成后将其唤醒,放回就绪队列。

地址变换:
物理地址 = 主存块号 * 块长 + 页内地址

2.2、请求分段存储管理

references:基本分段存储管理方式

段表机制和页表机制不同在于,页表分配的内存块都是固定大小的,段表分配的段大小都是不固定长的。

段表字段:
段号、段长、段基址(是啥)、段内地址

当所要访问的段不存在时,产生一个缺段中断,将所缺的段调入内存。

地址变换:
物理地址=段基址+段内地址

分段的共享:
每个表项都是共享段的信息,有个共享进程计算器。

分段保护:
地址越界保护:段号超过段表长度、偏移量大于段长,中断处理
访问控制保护:控制段的访问方式(访问字段)
环保护机构

2.3、请求段页式存储管理

先查询段表,再查询页表。
自己看吧

2.4、分段和分页的区别

  1. 目的:分页存储是由于系统管理的需要;分段是为了用户的需要
  2. 大小:页的大小固定,段的大小不固定;
  3. 地址:页的地址是一维的(通过一个虚地址就能直接计算出物理地址),段的地址是二维的(拿到一个虚地址,得到段号和段内地址,然后才能知道物理地址);
  4. 内存碎片:页没有外部碎片(大小固定)但有内部碎片(填不满);段没有内部碎片(大小可变)但有外部碎片(置换的时候)

3、页面置换算法

  1. 最佳置换算法:需要知道哪些页面会用到以及使用的时间。算法会先换出不会用到的页面,如果都会用到那就换出最晚用到的页面。(这个算法几乎是不可能实现的)
  2. 先进先出算法(FIFO):在内存中待的时间最长的页置换出。运行速度快(队列实现),开销少,但容易将重要的页面换出。
  3. 最近最少使用法(LRU):选择最长时间没访问的页面置换出,通过访问字段实现。需要寄存器(原理,寄存器表示的值越小的越久没使用)和栈的支持(每次将最新的拿出来放在栈顶)。
  4. CLOCK算法/最近未用算法(NRU):
    将所有页面分为以下四类:
  • 最近未访问,未修改(u = 0,m = 0)
  • 最近被访问,未修改(u = 1,m = 0)
  • 最近未访问,被修改(u = 0,m = 1)
  • 最近被访问,被修改(u = 1,m = 1)
  1. 最不经常使用算法(LFU):根据使用次数来判断。

扫描帧缓冲区,选择(u = 0,m = 0)的第一个进行置换;不存在就选择(u = 1,m = 0)第一个进行替换,此时,将扫描过的帧的u置为0;如果还没找到,那么刚才那步已经将所有u置为0了,那么再重复刚才两步肯定能找到一个可以置换的。
CLOCK算法性能接近LRU,效率也相对较高。

4、页面分配、置换策略

references:
页面分配策略

驻留集:给进程分配的物理内存块的集合
固定分配:驻留集不变,分多少是多少
可变分配:先分配一定数量内存块,运行期间,驻留集可变
局部置换:缺页时只能置换进程自己的内存块
全局置换:可将操作系统保留的空闲块分配给缺页的进程,也可以将别的进程的内存块置换到外存,再分配给缺页的进程。

4.1、页面分配置换策略

  1. 固定分配局部置换:为每个进程分配一定数量的物理块,发生缺页只能从进程自己的内存块置换。
  2. 可变分配全局置换:OS为进程分配一定量的物理块,自身也保持一个空闲物理块队列,如果进程发生缺页,则将空闲物理块队列中取出一个空闲物理块分配给进程,将缺的页装入其中。如果队列空了,就找未锁定的页面换出到外存,再分配给缺页进程。(只要缺页就给分配新的物理块
  3. 可变分配局部置换:为每个进程分配一定数量的物理块,发生缺页只能从进程自己的内存块置换。如果频繁缺页,分配新的物理块;如果缺页率很低,就减少进程持有的物理块。

4.2、调入的时机

  1. 预调页策略:一次调入若干个相邻的页面。但成功率低,通常用于进程首次调入。
  2. 请求调页策略:缺页时调入。IO开销大。

4.3、调入的空间

请求分页系统中的外存分为两部分:用于存放文件的文件区和用于存放对换页面的对换区。
对换区通常连续分配空间,文件区离散存放,故通常对换区IO速度更快。

  1. 对换区空间足够:将文件调入对换区,从对换区调入页面。
  2. 对换区空间不足:不会被修改的文件直接从文件区调入,换出时因为没被修改就不用写入;对于被修改的,将他们换出到对换区,以后从对换区调入。

5、优缺点

优点:

  1. 理论上扩大了内存,弥补了物理内存不足的缺点
  2. 有内存保护机制,用户进程不被允许读写内核代码和数据结构,不被允许读写其他进程的私有内存等等
  3. 需要分配连续空间时,可在虚拟地址空间分配连续空间,实际物理内存使用离散分配

缺点:

  1. 需要建立很多其他数据结构占据内存
  2. 地址转换需要耗时
  3. 页面置换使用的是磁盘IO,很耗时
  4. 分页存储时,可能会产生内部碎片

6、颠簸

本质上是指频繁的页调度行为,置换了一个页又马上又调了进来,因此不断产生缺页中断,导致整个系统效率下降。
解决:

  1. 如果是因为页面置换算法的失误,调换算法
  2. 如果是因为运行的程序太多,则降低数量
  3. 增加物理内存
posted @ 2020-03-29 21:56  KirinSB  阅读(277)  评论(0编辑  收藏  举报