操作系统复习大纲笔记

1. 第一章

1.1 指令执行的基本指令周期

基本指令周期:取指令、执行

基本流程:开始->将PC所指地址中的指令读入IR,PC++()->执行IR中的指令()->结束

IR:instruction register,指令寄存器

PC:program counter,程序计数器

四类指令:

  • 处理器-存储器:在和传送数据
  • 处理器-I/O:和间传送数据
  • 数据处理:算术/逻辑运算
  • 控制转移:设置PC值,改变执行顺序

1.2 中断的定义与分类

  • 中断的定义:由于发生某些事件,暂停当前程序在CPU上的运行,转而去执行相应事件的。待处理完成后,再返回断点或者
  • 中断分类
    • 程序中断:由程序指令的执行结果产生,如算术溢出、除数为0、非法指令、地址越界、缺页、断点调试等
    • 时钟中断:CPU内部的计时器产生
    • I/O中断:I/O控制器正常或者异常结束时,由I/O控制器产生
    • 硬件失效中断:掉电、内存奇偶校验错等硬件故障

1.3 中断的处理

1.3.1 对程序控制流的影响

  • 无中断时的处理流程:首先程序在CPU上运行,正在执行非I/O指令,此时程序提出I/O请求,程序流被打乱,开始执行I/O程序,先执行,然后执行I/O操作,完成I/O后设置完成状态。此时回到原程序流,继续执行剩余的程序指令流。
  • 有中断时的处理流程:首先程序在CPU上运行,正在执行非I/O指令,此时程序提出I/O请求,程序流被打乱,开始执行I/O程序,先执行,然后在I/O操作开始执行的同时,CPU回到原程序流,继续执行剩余的非I/O指令,当I/O完毕时,发出中断信 ,中断处理程序启动,完成剩余的I/O程序操作(设置完成状态等),完成后回到原程序流继续执行。
  • 在,I/O操作分为短I/O和长I/O:
    • 短I/O:下段非I/O指令尚未执行完,本次I/O已经结束,并发出中断
    • 长I/O:本次I/O请求时间长,尚未结束时已经发生了下次的I/O请求,则将该I/O请求排入请求队列,顺序处理各个请求

1.3.2 对CPU的影响

  • 无中断时:CPU和I/O设备是工作,也就是一个设备必须等待另外一个设备操作结束
  • 有中断时:CPU和I/O设备是工作,CPU完成更多任务,I/O操作期间,CPU继续执行其他任务,提高CPU利用率

1.3.3 中断处理机制

  • CPU在执行完一条指令之后、执行下一条指令之前,检测并处理中断
  • 有中断时的指令周期
    • 此时指令周期可以分为三个阶段,也就是取指阶段、执行阶段、中断阶段
    • 大致流程:①开始->②进入取指阶段(取下一条指令)->③进入执行阶段(执行指令)->如果允许中断,进入④,如果不允许中断,返回②,④检查中断信 ,初始化中断处理程序,当程序流中的所有指令都执行完毕后,停止。

1.3.4 中断处理-硬件连接

  • CPU和之间用总线上的连接。设备发出中断后,CPU响应中断

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ssiWYGx-1655605190868)(.image硬件响应.png)]

  • 看图说话:首先disk作为I/O设备,进行I/O,当I/O操作结束之后,DISK向中断控制器发出中断信 ,中断控制器(中断请求线)转发中断信 给CPU,CPU在执行完一条指令后,执行下一条指令前,接收该中断信 ,CPU处理该中断。

1.3.4 中断处理的软件实现

  • 每个中断都有一个中断向量 ,是该中断在中断向量表中的编
  • 中断向量:中断处理程序的(内存)入口地址。4B/向量
  • 中断向量表:所有中断向量的集合,一般位于内存的0地址起始处(长1KB),在开机启动时从磁盘装入内存
  • 以上的数据结构规定了一种中断处理模式,每一种处理有自己的编 ,根据此编 可以在中断向量表中找到对应的中断类型,在对应的中断类型中对应一个中断处理程序(地址),当发生某种中断时,依照这个链条去寻找中断处理程序

1.3.5 中断处理的过程

  • 由硬件执行的部分:设备发出中断信 ->CPU执行完当前指令->CPU向设备发中断应答信 ->CPU将PSW和PC压栈(保存现场)->根据(中断向量表),CPU设置新PC值
  • 由中断处理程序执行的部分:将其它寄存器的值压栈->执行中断处理程序->恢复被中断程序的现场(包括原PSW和原PC)->返回原程序断点,继续执行

1.3.6 多个中断-两种处理方法

  • 顺序处理:当处理一个中断时,禁止中断。多个中断被顺序处理。
    • 禁止中断(关中断):CPU的PSW的中断禁止位=0,则不响应新的中断
    • 开中断:中断禁止位,CPU可以接收中断
  • 中断嵌套:允许高优先级的中断请求打断低级中断的处理。通常,中断源速度越快,其优先级越高
    • 中断屏蔽:设置PSW的中断屏蔽码(当前程序的中断优先级),选择性地封锁部分中断,当发生更高优先级的中断时才响应
    • 有些中断(如掉电)是不能屏蔽甚至不能禁止的

1.4 存储器层次

  • 内存:CPU能直接访问的唯一大型存储介质
  • 为,用实现虚拟内存
  • 为,CPU首先访问Cache,不命中时再访问内存且复制进Cache。
  • Cache-内存两级存储器:当Cache命中率很高时,平均存取时间接近于Cache访问速度
  • 设忽略用于确定Cache是否命中的时间。
  • 二级存储器(Cache-内存)下内存的平均存取时间:若T1为,T2为,H为,则访问数据的平均存取时间为 H T 1 + ( 1 H ) ( T 2 + T 1 ) H*T1+(1-H)*(T2+T1) H/span>T1+(1/span>H)/span>(T2+T1)
  • 不同CPU访问Cache-内存时的方式不同(了解)
    • 第一种在Cache不命中时,数据从内存->Cache->寄存器
    • 第二种则从内存直接送到寄存器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rxWIumcN-1655605190869)(.imageCPU-Cache.png)]

1.5 程序局部性原理

  • 两级存储器有效的原因:
    • 时间局部性:在一段小的内,被访问过的某指令或者数据,可能很快就会被
    • 空间局部性:在一段小的时间间隔内,程序访问的地址空间往往
    • 大多顺序执行;经常有循环;过程调用深度有限;数据常为数组、记录;不是所有的代码都需要执行
  • 让内存包含所有的(或大部分)指令和数据,而当前访问的”簇“包含在Cache中,可达到高命中率
  • 类似地,在虚拟内存中,由”Cache-内存-硬盘”构成三级存储器

怎样改变空间局部性和时间局部性/p>

空间局部性:更大的Cache块,将数据预取到块中

时间局部性:Cache中保留最近访问的代码和数据

  • 空间局部性
    • 执行完第一条指令,执行第二条指令
    • 不断访问数组a[]
  • 时间局部性
    • 循环体被频繁执行
    • a[i]在循环内部被访问了10次

2. 第二章

2.1 操作系统的发展过程及其衍生出来的操作系统类型

术语简介:

RAM:主存,与CPU进行直接数据交换的内部存储器

ROM:ROM所存数据,一般是装入整机前事先写好的,整机工作过程中只能读出,而不像随机存储器那样能快速地、方便地加以改写。

BIOS(Basic Input Output System):保存着计算机最重要的基本输入输出的程序、系统设置信息、开机上电自检程序和系统启动自检程序。

  • 发展过程
    • 人工操作阶段-无OS
    • 简单批处理系统-监控程序():使磁带上的一批作业自动、顺序地逐个运行,内存中只有一个作业,故称为单道批处理,监控程序所在的系统内存区含有:、、、
      • 作业的组成:用户的程序、数据、作业说明书
      • 脱机I/O:程序员把程序卡片拿到卫星机上,读入到”输入磁带”上,操作员把”输入磁带“放进主机,作业在Monitor控制下自动逐个(单道运行),运行结果写到输出磁带上,输出磁带送到卫星机上去打印
    • 多道程序设计:由于中断、磁盘、DMA等的引入,使得内存中可以同时存在多个作业,并发执行
      • 并发:多个事件在同一时间间隔内发生
      • 并行:多个事件在同一时刻发生
    • 当正执行的作业需要进行I/O时,可以让出CPU给内存中的其它作业去运行,以提高资源利用率
    • 多道批处理OS
      • 减少了因CPU与I/O设备串行工作导致的CPU空闲。CPU与I/O设备并行工作,资源利用率高,吞吐率高
      • 周转时间长,用户交互性差,整个作业完成后或者中间出错时,才与用户交互,不利于调试和修改
    • 分时系统
      • 把CPU分割成时间片,每个用户依次轮流使用时间片
      • 多个用户通过终端与主机交互。他们的作业按照时间片轮转运行。作业的响应时间短
      • 为了满足用户交互和及时响应的要求
    • 批处理OS和分时OS的比较
批处理OS 分时OS
主要目标 提高资源利用率 减小响应时间
OS指令源 作业控制语言,作业中的指令 终端输入的命令
  • 实时操作系统:用于实时控制系统和实时信息处理系统
    • 严格的时间限制和及时响应
    • 高可靠性;如采用冗余的软件或者硬件
  • 兼有几种OS特征的通用OS中的前台和后台处理
    • 前台(分时)
    • 后台(批处理)

2.2 多道程序设计如何提高CPU资源利用率

  • 当正执行的作业需要进行I/O时,可以让出CPU给内存中的其它作业去运行,以提高资源利用率

3. 第三章

3.1 进程映像

  • 进程:程序在一个数据集上的一次执行过程
    • 进程与程序的联系与区别
      • 程序是静态的;进程是动态的(动态产生并且消亡),且一个进程运行时可以创建其他进程
      • 一个进程可对应一个进程,也可以对应多个进程(只要进程所对应的数据集不同)
    • 进程的组成(进程映像):
      • 程序代码
      • 数据集、栈
      • 进程控制块(PCB):PCB是进程存在的唯一标识,OS根据PCB中的属性控制进程
  • 上下文:进程运行时CPU的寄存器数据集合(现场),包括用户可见寄存器和控制/状态寄存器等
  • 分派器(进程调度程序)调度时发生:保存旧进程的上下文到它的PCB,从新进程的PCB恢复它的上下文到寄存器
  • 引入进程,由于实现了并发执行和资源共享,可带来提高和的好处,但却增加了系统的和

3.2 进程的创建和终止

  • :OS为该进程建立PCB,分配内存空间
  • 导致进程创建的原因
    • 新的批处理作业:作业提交后,开始运行时创建进程
    • 交互登录:新用户登录和接收用户命令时创建进程
    • OS提供服务:如控制打印、 络通信等的服务进程
    • 父进程派生子进程:父进程请求创建子进程
  • :回收内存,释放资源,销毁PCB
  • 导致进程终止的原因
    • 进程正常运行完毕;用户或OS干预;父进程请求或父进程已终止;运行时发生的各种故障和错误

3.3 五状态模型-五状态进程模型

  • (new):进程正被创建。分配内存后将被设置为就绪态
  • (ready):进程已得到除CPU以外的其他所需资源
  • (running):进程的指令正被执行
  • (blocked):进程正等待资源或某事件发生
  • (exit):进程已正常或异常结束。回收资源,善后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bF1rz6MN-1655605190869)(./image/五状态模型.png)]

  • 看图说话:首先一个进程被新建,进入,新建后加载资源,加载除了CPU之外的资源后进入,等待被分派器调度,当它被调度时就进入,此时如果中途没有被阻塞,则会一直在CPU上运行直到结束,如果发生了意外之中的事情,则进程等待某件事发生,进入,等待这个原因解除之后,回到,等待分派器调度

  • 进程队列

    • 就绪队列:所有就绪进程按FCFS或优先级顺序排队
    • 等待(阻塞)队列:每一种等待事件对应于一个队列。例如:等待某一I/O设备的进程组成一个设备阻塞队列

    一个多任务双核处理机系统,其操作系统是UNIX,PCB表的规模是100行,则:

    最多有____2___个进程处于运行态;

    最多有____98____个进程处于就绪态;

    最多有____100___个进程处于阻塞态。

    设某UNIX中每个用户创建进程数最大为50个, 现有一用户执行某程序,该程序执行一死循环,循环创建新子进程。则当该进程创建了___49___个子 进程后将不能再创建,该进程处于__阻__塞状态。

  • 被挂起的进程-两种挂起态

    • 挂起的根本原因:内存不足,不得不把部分进程交换到磁盘

    • 就绪挂起态、阻塞挂起态:外存就绪/阻塞态。由于内存有限,将原位于内存的就绪/阻塞进程(代码数据)换出到外存(磁盘)上

    • 解除挂起:当挂起进程优先级高或者内存空间足够时,把位于磁盘的挂起进程(代码数据)换入到内存

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KV5ZX9iC-1655605190870)(.image两种挂起态.png)]

    • 看图说话:此时存在内存不足的风险,当进程被新建,进入时,会做判断,当内存不足时,进程依然会加载资源,但是加载资源完毕后会被交换到磁盘中,进入,当有足够的内存或者优先级高时,就会解除挂起,该进程进入,还有一条路线就是当内存充足的时候,就会直接由进入就绪态。

    • 当内存中的就绪态进程过多而导致内存不足时,就会将一些处于的进程挂起,交换到磁盘上,成为

    • 当就绪态被调度时,就会进入运行态,则进入,当运行了规定的时钟周期而仍未进入到退出态时,就会超时,回到就绪态,当在运行过程中需要等待某事件发生时,就会进入阻塞态,当某事发生后,阻塞态又会重新回到就绪态

    • 当内存中存在大量的阻塞态进程时,而此时内存空间不足时,就会选择将一部分存在于内存中的阻塞态进程交换到磁盘,此时称为,成为阻塞挂起态有两种方向,第一种,没有发生意外的事情,该进程会直接解除挂起,放回内存,成为阻塞态。第二种,发生了某事,此时变为。

假设有些进程处于就绪态,有些处于就绪挂起态,且至少有一个就绪挂起态进程的优先级高于所有就绪态进程。有两种极端策略:
1、总是调度处于就绪态的进程,以减少交换;
2、总是调度优先级最高的进程,会导致不必要的交换。

把就绪挂起进程降低 (1或2个)优先级,如果它仍然高于所有就绪进程的最高优先级,那么就将它换入内存执行。

3.4 进程控制块PCB

  • PCB(Process Control Block):进程属性的集合

  • OS进程表中包含所有进程的PCB

  • 创建新进程时,分配进程表中的一个空闲PCB,填写属性

  • 进程终止时回收PCB

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DTKlwUrq-1655605190871)(.imagePCB访问规则.png)]

  • PCB的属性与典型字段

    • PCB的索引(PID)唯一地标识该进程

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tG6NKg3e-1655605190871)(.imagePCB字段.png)]

    • 进程控制结构-PSW

      • 程序状态字寄存器:指明CPU当前特权级别、中断屏蔽码(中断优先级)等

3.5 执行模式的切换:用户态和系统态

  • CPU有两种执行模式

    • 用户态:只能执行非特权指令
    • 系统态:也称为核心态、内核态、特权态、控制态、管态。可以执行所有指令(特权指令和非特权指令),使用所有资源以及改变CPU状态
  • 两类指令

    • 特权指令:在系统态下执行的指令(OS内核使用)
    • 非特权指令:用户态下执行(用户程序)
  • 执行模式

    • 当CPU要执行特权指令时,会引起”陷入trap”,即CPU由用户态切换到系统态(称为模式切换),然后去执行OS内核中的一段(特权指令)代码。
  • 何时CPU从用户态到系统态/p>

    • 执行系统调用(即内核代码,由OS提供服务)时
    • 发生中断或者异常时,执行中断处理程序
  • 如何从系统态到用户态/p>

    • 系统调用或中断处理完毕后,执行IRET(中断返回)指令,恢复原进程的PSW,回到用户态
    • 中断嵌套时响应另一中断、中断返回在系统态运行时也可以响应中断

3.6 进程切换

  • 何时进行进程切换
    • 中断发生时:如时钟中断,当前进程时间片结束,让出CPU,调度新进程,因此发生新旧进程的切换
    • 陷阱发生时:当前进程的指令产生错误或错误,非致命时重试或者 告,致命时将结束本进程,调度新进程
    • 当前进程执行系统调用时,通常会被阻塞,让出CPU
  • 进程切换的步骤
    • 保存当前进程的CPU上下文(寄存器现场),更新其PCB;将其PCB转移到相应的就绪或阻塞状态队列
    • 选择(调度)另外一个就绪进程,准备执行
    • 更新该进程PCB,从就绪队列移出,更新内存管理的数据结构(如设置页表指针、基址/界限寄存器),将该进程的上下文恢复到CPU寄存器中

3.7 fork()

  • UNIX中,父进程通过系统调用fork()创建子进程。fork()调用一次,但返回两次,向父进程返回子进程的PID,向子进程返回0

4.第四章

4.1 进程和线程的区别

  • 进程:分配资源的单位,不频繁进行切换
  • 线程:被调度运行的单位,不拥有资源,可频繁调度切换,轻装运行,也称为轻量级LWP
    • 多个线程共享进程空间(内存、文件),通信快
    • 子进程空间各自独立,通信时需要借助IPC机制(进程间通信,消息、管道、信 、共享内存区等),慢
  • 区别解析
    • 是资源分配和抢占CPU的单位,进程的资源以及地址空间供其所有线程共享
    • 线程不拥有系统资源,线程执行环境小,同一进程的不同线程间切换和通信时开销小
    • 线程是一个进程内部的,一个进程可派生多个线程(执行多条代码流),线程间并发运行

4.2 线程的优点

  • 创建/终止一个线程比创建/终止进程的时间要少
  • 上下文切换开销少:对进程不频繁地进行切换同一进程内各进程的切换速度快
  • 资源共享:进程的资源供其所有线程共享;线程间共享内存,通信方便
  • 并发程度高,可利用多处理器结构

4.3 线程的三种状态

  • 线程的基本状态:、、
  • 挂起/终止一个进程会导致其所有线程被同时挂起/终止
  • 与进程类似,多个线程并发执行可以提高系统效率,但需要线程间的同步互斥

4.4 用户级线程和内核级线程的特点

  • 线程可分为两类
    • 用户级线程(User-Level Thread)
    • 内核级线程(Kernel-Level Thread,KLT),也称内核支持的线程、轻量级进程
  • 用户级线程
    • 用户级线程的创建、撤销、调度与OS内核无关,由用户空间中的线程完成。OS内核并不知道用户级线程的存在,进程各自管理各自的线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCoA1FCK-1655605190872)(.image进程状态例子.png)]

  • 用户级线程的优点

    • 一个进程的ULT切换时,不需要切换到系统态
    • 进程自己决定如何调度线程,更灵活
    • 只要有线程库,用户级线程可以在任何OS上运行,而不需要修改底层的OS代码
  • 用户级线程的缺点

    • ULT提出阻塞式系统调用时,将阻塞所属进程
    • ULT对OS不可见,CPU分配以进程为单位,因此不能利用多CPU结构
  • 内核级线程

    • 内核级线程的创建、撤销、调度以及同步互斥由OS内核完成,OS通过TCB控制内核级线程
    • 对内核级线程的管理类似于进程
    • 内核级线程的优点
      • 可以同时把一个进程的多个KLT调度到多个CPU上
      • 一个KLT阻塞时,OS可调度该进程的另一个KLT
    • 内核级线程的缺点
      • 在调度KLT时,需要CPU切换到系统态,开销大
  • 用户级线程内核级线程的对比

    用户级线程 内核级线程
    调度和切换 在一个进程的线程切换,快。以进程为单位分配CPU。不能利用多CPU结构 OS管理内核级线程和进程,以内核级线程为单位分配CPU,可以利用多CPU结构
    当调用阻塞式系统调用时 阻塞该用户级线程所属的进程 只阻塞内核级线程本身
    运行时间 一个进程内所有用户级线程分享一个时间片 每个内核级线程运行一个时间片

5.第五章

5.1 互斥的概念

  • 当一个进程正在临界区中访问临界资源时,其它进程不能进入临界区

5.2 临界资源与临界区

  • 临界资源:一次仅允许一个进程独占使用的不可剥夺资源
  • 临界区:进程访问临界资源的那段程序代码。一次仅允许一个进程在临界区中执行

5.3 信 量定义,semWait,semSignal含义

  • 信 量:不要求忙等的同步互斥工具,用于进程间传递信 的一个整数值,在信 量上只可进行三种操作,即初始化、递减和增加,这三种操作都是原子操作,递减操作作用于阻塞一个进程,递增操作用于接触一个进程的阻塞,信 量也称为计数信 量或一般信 量
  • SemWait(s):本进程请求分配一个资源
  • SemSignal(s):本进程释放一个资源

5.4 信 量原语定义

5.5 用信 量实现同步与互斥

  • 实现互斥
    • 对每一临界资源设置一个信 量s,初值=1
    • 实现互斥:每个进程在进入临界区之前,执行semWait(s);退出临界区后,执行semSignal(s)
    • 临界区内不应有可能引起阻塞或者死锁的因素
  • 实现同步

    • 同步时,对每一类资源设一信 量s,初值>=0,表示可用资源个数
      • 资源:可以是同一物理资源的不同状态,如缓冲区的空与满。对空缓冲和满缓冲分别设置信 量
  • 要求实现:P1执行过A后,P2才能执行B,设一信 量s,初值为0

5.6 有限缓冲的生产者/消费者问题

  • 生产者/消费者问题介绍

    • 一组生产者进程产生数据,放到缓冲区
    • 一组消费者进程从缓冲区取出数据使用
    • 有限缓冲:假设缓冲池大小固定,包含k个缓冲区,生产者和消费者公用一个循环缓冲池
    • 无限缓冲:缓冲数量无限制
  • 有限缓冲问题

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FsMFmhDo-1655605190872)(H:2022年上学期期末复习资料操作系统笔记文档image优先缓冲模型.png)]

    • 一组生产者和进程和一组消费者进程共用一个

    • 有sizeofbuffer个缓冲区的缓冲池来交换数据

    • 资源、约束条件以及信 量设置

      • 互斥:缓冲池一次只能让一个进程访问,设一信 量s,初值为1
      • 同步:生产者需要来发送数据,设一信 量empty,初值为sizeofbuffer
      • 同步:消费者需要来获取数据,设一信 量full,初值为0

5.7 进程间通过”消息传递”交换信息:无阻塞send和阻塞receive

  • 消息传递的原语

  • send(P,message)-给进程P发消息message

  • receive(Q,message)-接收来自进程Q的消息

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kOH3nf6u-1655605190873)(.image消息传递模型.png)]

  • 同步:发送者发出消息后,接收者才能接收

  • 当一个进程执行send()时,该进程可以

    • 不阻塞,继续执行
    • 被阻塞,直到这个消息被接收者接收
  • 当一个进程执行receive()时,该进程可以

    • 不阻塞,直到接收已发来的消息或放弃接收,继续执行
    • 被阻塞,直到所等待的消息到达
  • 无阻塞式send和阻塞式receive最常用

  • send和receive如何指明接收者和发送者

    • 直接寻址:指明目标进程或源进程的标识ID,公共服务进程使用receive()时,不指明源进程(隐式)
    • 间接寻址:通过信箱发送和接收消息

6.第六章

6.1 死锁原因:竞争资源、进程推进顺序不当

  • 死锁原理:当一组进程中的每个进程都在等待某个事件(所请求的资源被释放),而只有在这组进程中的其他阻塞进程才能触发该事件,称这组进程发生死锁
  • 死锁原因
    • 竞争资源
    • 进程推进顺序不当

6.2 资源分配图(若死锁,则资源分配图中必有环路,但有环路时不一定死锁)

  • 资源分配图:有向图,描述资源和进程状态

    • 进程节点:P
    • 资源节点:R,一个圆点代表一个资源实例
    • 请求边:进程->资源,

      声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年5月16日
下一篇 2022年5月16日

相关推荐