操作系统

🌸 您好,欢迎您的阅读,等君久矣,愿与君畅谈.
🔭 § 始于颜值 § 陷于才华 § 忠于人品 §
📫 希望我们可以进一步交流,共同学习,共同探索未知的技术世界 稀土掘金 OR GitHub.


# 进程、线程
  • 进程:进程是系统进行资源分配和调度的一个独立单位,是系统中并发执行的单位,资源分配的基本单位、最小单位
    • 运行中的程序,就被称进程
    • 一个进程的活动期间至少具备三种基本状态,即运行状态、就绪状态、阻塞状态
      • 运行状态(Running): 该时刻进程占用 CPU;
      • 就绪状态(Ready): 可运行,由于其他进程处于运行状态而暂时停止运行;
      • 阻塞状态(Blocked): 该进程正在等待某一事件发生(如等待输入 / 输出操作的完成)而暂时停止运行,这时,即使给它 CPU 控制权,它也无法运行;
    • 进程的另外两个基本状态
      • 创建状态(new): 进程正在被创建时的状态
      • 结束状态(Exit): 进程正在从系统中消失时的状态
    • 进程的挂起状态也分为两种
      • 阻塞挂起状态:进程在外存(硬盘)并等待某个事件的出现
      • 就绪挂起状态:进程在外存(硬盘),但只要进入内存,即刻立刻运行
    • PCB 进程控制块 是进程存在的唯一标识
    • 进程的描述信息
      • 进程标识符:标识各个进程,每个进程都有一个并且唯一的标识符
      • 用户标识符:进程归属的用户,用户标识符主要为共享和保护服务
    • 进程优先级:进程抢占 CPU 时的优先级
    • CPU 中各个寄存器的值,当进程被切换时,CPU 的状态信息都会被保存在相应的 PCB 中,以便进程重新执行时,能从断点处继续执行。
  • 线程:线程是进程的一个实体,也是 CPU 调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,有时被称为轻权进程或轻量级进程
    • 线程是进程当中的一条执行流程,同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。
    • 线程的实现主要有三种线程的实现方式
      • 用户线程 (User Thread): 在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理;
      • 内核线程 (Kernel Thread): 在内核中实现的线程,是由内核管理的线程;
      • 轻量级进程 (LightWeight Process): 在内核中来支持用户线程;
      • 用户线程与内核线程的对应关系
        • 第一种关系是多对一的关系,也就是多个用户线程对应同一个内核线程
        • 第二种是一对一的关系,也就是一个用户线程对应一个内核线程
        • 第三种是多对多的关系,也就是多个用户线程对应到多个内核线程
      • 用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等
      • 线程的优点
        • 一个进程中可以同时存在多个线程
        • 各个线程之间可以并发执行
        • 各个线程之间可以共享地址空间和文件等资源
      • 线程的缺点
        • 当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃(这里是针对 C/C++ 语言,Java 语言中的线程奔溃不会造成进程崩溃
        • 内核线程是由操作系统管理的,线程对应的 TCB 自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责
  • 进程 / 线程间通信方式:进程间通信 (IPC,InterProcess Communication) 是指在不同进程之间传播或交换信息
    • IPC 的方式通常有管道 (包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams 等,其中 Socket 和 Streams 支持不同主机上的两个进程 IPC。
    • 管道
      • 它是半双工的,具有固定的读端和写端
      • 它只能用于父子进程或者兄弟进程之间的进程的通信
      • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的 read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中
    • 命名管道
      • FIFO 可以在无关的进程之间交换数据,与无名管道不同
      • FIFO 有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中
    • 消息队列
      • 消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符 ID 来标识
      • 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
      • 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除
      • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取
    • 信号量
      • 信号量(semaphore)是一个计数器。用于实现进程间的互斥与同步,而不是用于存储进程间通信数据
      • 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存
      • 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作
      • 每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数
      • 支持信号量组
    • 共享内存
      • 共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区
      • 共享内存是最快的一种 IPC,因为进程是直接对内存进行存取
    • Socket 通信:不同主机的进程间通信,那么就需要 Socket 通信,Socket 实际上不仅用于不同的主机进程间通信,还可以用于本地主机进程间通信
      • 根据创建 Socket 的类型不同,分为三种常见的通信方式
      • 一个是基于 TCP 协议的通信方式
      • 一个是基于 UDP 协议的通信方式
      • 一个是本地进程间通信方式
    • 线程通信间的方式
      • 同个进程下的线程之间都是共享进程的资源,只要是共享变量都可以做到线程间通信
      • 对于线程间关注的不是通信方式,而是关注多线程竞争共享资源的问题,信号量也同样可以在线程间实现互斥与同步
        • 互斥的方式,可保证任意时刻只有一个线程访问共享资源
        • 同步的方式,可保证线程 A 应在线程 B 之前执行
# 并发与并行
  • 并行是在不同实体上的多个事件,并发是在同一实体上的多个事件
  • 并发:指两个或多个事件在同一时间间隔发生
  • 并行:指两个或者多个事件在同一时刻发生
# 用户态和内核态
  • 内核态:处于内核态的 CPU 可以访问任意的数据,并且占用 CPU 不会发生抢占情况,一般处于特权级 0 的状态我们称之为内核态
  • 用户态:处于用户态的 CPU 只能受限的访问内存,并且不允许访问外围设备,用户态下的 CPU 不允许独占,也就是说 CPU 能够被其他程序获取
# 局部性原理:主要分为时间局部性和空间局部性。

时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环)
空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)

# 异常和中断
  • 异常:当我们在敲击键盘的同时就会产生中断,当硬盘读写完数据之后也会产生中断,所以我们需要知道,中断是由硬件设备产生的,而它们从物理上说就是电信号,它们通过中断控制器发送给 CPU,接着 CPU 判断收到的中断来自于哪个硬件设备(这定义在内核中),最后,由 CPU 发送给内核,有内核处理中断
  • 中断:CPU 处理程序的时候一旦程序不在内存中,会产生缺页异常;当运行除法程序时,当除数为 0 时,又会产生除 0 异常。所以异常是由 CPU 产生的,同时它会发送给内核,要求内核处理这些异常
  • 相同点
    • 由 CPU 发送给内核,由内核去处理
  • 不同点
    • 产生源不相同,异常是由 CPU 产生的,而中断是由硬件设备产生的
    • 内核需要根据是异常还是中断调用不同的处理程序
  • 中断不是时钟同步的,这意味着中断可能随时到来;异常由于是 CPU 产生的,所以它是时钟同步的,当处理中断时,处于中断上下文中;处理异常时,处于进程上下文中
# 原子操作
  • 处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作
  • 处理器会自动保证基本的内存操作的原子性。处理器保证从系统内存中读取或者写入一个字节是原子的,当一个处理器读取一个字节时,其他处理器不能访问这个字节的内存地址
  • 原子性方法
    • 使用总线锁保证原子性
    • 使用缓存锁保证原子性
# 服务器高并发解决方案
  • 应用数据与静态资源分离将静态资源 (图片,视频,js,css 等) 单独保存到专门的静态资源服务器中,在客户端访问的时候从静态资源服务器中返回静态资源,从主服务器中返回应用数据
  • 客户端缓存效率比较高,消耗资源最小的就是纯静态的 html 页面,所以可以把网站上的页面尽可能用静态的来实现,在页面过期或者有数据更新之后再将页面重新缓存。或先生成静态页面,然后用 ajax 异步请求获取动态数据
  • 集群和分布式
    • 集群是所有的服务器都有相同的功能,请求哪台都可以,主要起分流作用
    • 分布式是将不同的业务放到不同的服务器中,处理一个请求可能需要使用到多台服务器,起到加快请求处理的速度
    • 反向代理在访问服务器的时候,服务器通过别的服务器获取资源或结果返回给客户端
# 抖动或颠簸现象
  • 刚刚换出的页面马上又要换入内存,刚刚换入的页面马上又要换出外存,这种频繁的页面调度行为称为抖动或颠簸
  • 产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数 (分配给进程的物理块不够)
  • 为进程分配的物理块太少,会使进程发生抖动现象;为进程分配的物理块太多,又会降低系统整体的并发度,降低某些资源的利用率,为了研究应该为每个进程分配多少个物理块,Denning 提出了进程工作集的概念

操作系统
http://example.com/2020/04/14/C001_操作系统/
作者
XGG
发布于
2020年4月14日
更新于
2023年6月3日
许可协议