操作系统

"learning……"

Posted by Ryan on January 13, 2025

风花雪月本闲,而扰攘者自冗…..

纯理论八股复习

image

操作系统绪论

操作系统分类

  • 分时操作系统
  • 实时操作系统
    • 硬实时:导弹、通信
    • 软实时:订票

操作系统运行机制

CPU上运行两种程序:区分内核程序(操作系统kernel开发)和应用程序(应用开发)

image

  1. 刚开机时,CPU为内核态,操作系统内核程序先上CPU运行
  2. 开机完成后,用户可以启动某个应用程序
  3. 操作系统在合适的时候主动让出CPU,让该程序上CPU运行
  4. 应用程序运行在用户态
  5. 用户态程序非法事件会导致中断产生

image

中断和异常

中断是操作系统夺回使用权的唯一途径,会让用户态切回内核态

中断分类:

  • 内中断:CPU执行某些指令时,发现非法行为(或者错误)产生,就会产生内中断;或者有用户态的“陷入指令”要求系统调用
    • 陷入trap(系统调用)
    • 故障fault
    • 终止abort(程序挂掉,可以吐核)
  • 外中断:
    • 时钟中断(alarm定时)
    • I/O中断

中断屏蔽->中断请求->中断管理器->中断向量表->中断处理函数

系统调用

系统调用是在内核态执行的,相当于软中断

常见的 Linux 系统调用分类:

  • 进程管理:用于创建、管理和终止进程。#include
    • fork():创建一个子进程。
    • exec():执行程序,替换当前进程的镜像。exec函数族。
    • exit():终止当前进程。
    • wait():等待子进程终止。
    • waitpid():等待指定子进程终止。
    • getpid():获取进程的 PID。
    • getppid():获取父进程的 PID。
    • kill():发送信号给进程。
  • 文件操作:用于文件和目录的创建、删除、读取、写入等操作。
    • open():打开文件或设备。
    • read():从文件读取数据。
    • write():将数据写入文件。
    • close():关闭文件。
    • stat():获取文件的状态信息。
    • unlink():删除文件。
    • mkdir():创建目录。
  • 内存管理:用于动态分配和管理内存。
    • mmap():映射文件或设备到内存。
    • munmap():解除内存映射。
    • brk():调整进程的堆内存。
    • sbrk():增长或减少数据段的大小。
  • 设备控制: 用于与设备交互的系统调用。
    • ioctl():控制设备的操作。
    • read():从设备读取数据。
    • write():向设备写入数据。
  • 信号处理: 用于处理进程间的信号通信。
    • signal():设置信号处理函数。
    • kill():向进程发送信号。
    • pause():使进程挂起,等待信号。
    • sigaction():设置信号处理方式。
  • 进程间通信: 用于在不同进程之间交换数据。
    • pipe():创建管道。
    • shmget():创建共享内存段。
    • mqueue():消息队列。
    • msgget():获取消息队列。
  • 网络通信: 用于套接字和网络协议的操作。
    • socket():创建网络套接字。
    • bind():将套接字与地址绑定。
    • connect():连接到远程服务器。
    • send():发送数据。
    • recv():接收数据。

操作系统内核

image

image

操作系统引导

Linux操作系统引导

  1. BIOS/UEFI 启动:硬件初始化,加载引导程序。
  2. 引导加载程序(GRUB 或其他):选择并加载操作系统内核。
  3. 内核初始化:加载设备驱动,挂载根文件系统,初始化系统。
  4. 用户空间启动:启动 init 或 systemd 进程,进入多用户模式。

虚拟机

image

image

进程

进程的组成

  • 进程控制块 – PCB
  • 程序段
  • 数据段

同一个程序可以产生多个进程,譬如QQ程序可以开多个窗口,登陆多个QQ,进程是程序的一次执行过程
每个进程都有唯一的PID,是由操作系统动态分配的

查看进程的命令

1
2
3
ps -ef        //显示所有进程的详细信息,包括 PID、父进程 PID、用户、CPU 时间、启动时间等。
ps -ef | grep process_name  //查找进程
top

image

进程的状态与转换

创建态->就绪态->运行态(CPU调度之后进入运行)->结束态
进程可以主动进入阻塞态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    +---------+        +---------+
    |创建(New)| -----> |就绪(Ready)|
    +---------+        +---------+
                          |  ^
      调度器分配CPU       |  |   时间片用尽
                          v  |
                     +---------+      等待完成
                     | 运行(Run)|  -------------------> +---------+
                     +---------+                        |等待(Wait)|
                         |                              +---------+
                         v
                     +---------+
                     |终止(Term)|
                     +---------+

image

image

image

进程控制

进程控制(状态转换)要一气呵成,不能被中断,所以要利用原语实现。
原语具有原子性,是原子操作,原语是指操作系统提供的一些低级别、不可分割的基本操作,用于实现对共享资源的同步与保护。原语通常由内核实现,保证其在执行过程中不会被中断,从而确保并发环境中的操作原子性。
PCB可以自动保存程序运行上下文,也就可以在程序下CPU之后重新运行时还原进程运行环境。

  1. 进程创建
    • 创建新的进程并分配资源。
    • 典型原语:fork()
  2. 进程执行
    • 替换当前进程的代码和数据,执行新的程序。
    • 典型原语:exec()函数族
  3. 进程终止
    • 终止进程的执行,释放资源。
    • 典型原语:exit() kill() _exit()
  4. 进程等待
    • 等待子进程状态变化(完成、被杀死等)。
    • 典型原语:wait() waitpid()
  5. 进程阻塞
    • 将进程状态从运行态切换为阻塞态,等待某条件满足。
    • 典型原语:sleep() pause()
  6. 进程唤醒
    • 将进程从阻塞态切换回就绪态。
    • 典型原语:信号机制 kill(pid, signal):向进程发送信号唤醒。
  7. 进程通信
    • 用于多个进程之间的交互与信息共享。
    • 典型原语:
      • 管道:pipe(),实现单向数据传输。
      • 共享内存:shmget(), shmat(), shmdt()。
      • 消息队列:msgget(), msgsnd(), msgrcv()。
      • 信号量:semget(), semop()。
  8. 优先级调整
    • 调整进程的优先级以改变调度顺序。
    • 典型原语:nice() setpriority()
  9. 进程组与会话
    • 管理多个进程的集合。
    • 典型原语:
      • getpid():获取当前进程 ID。
      • getppid():获取父进程 ID。
      • getpgrp() 和 setpgrp():获取或设置进程组。
      • setsid():创建新会话。

进程间通信 IPC

进程间通信(Inter-Process Communication, IPC)提供了多种机制,用于在不同进程之间传递数据、状态或同步操作。
管道:pipe(),实现单向数据传输。共享内存:shmget(), shmat(), shmdt()。消息队列:msgget(), msgsnd(), msgrcv()。信号量:semget(), semop()。

image

image

消息队列的直接通信方式:

image

消息队列的间接通信方式(信箱):

image

管道通信:

image

线程

线程概念

线程是程序中的基本执行单元,Linux 提供了多种实现和管理线程的方式。

image

image

线程基础

线程的特点:

  • 轻量级:线程比进程更轻量级,创建、销毁和切换的开销较小。
  • 共享资源:同一进程中的所有线程共享内存地址空间、文件描述符等资源,但有各自的寄存器和栈。
  • 独立调度:线程由操作系统独立调度,可以并发执行。
  • 通信成本低:线程间通信不需要使用复杂的机制(如 IPC),可以通过共享内存直接进行。

线程的状态:

  • 新建(New):线程对象被创建,但还未开始执行。
  • 就绪(Ready):线程已经创建并准备执行,等待 CPU 调度。
  • 运行(Running):线程正在被 CPU 执行。
  • 阻塞(Blocked):线程因等待某些资源或事件(如 I/O)而暂停执行。
  • 终止(Terminated):线程完成任务或被强制停止,进入终止状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
        +---------+      start()       +---------+
        |  新建   |------------------->|  就绪   |
        +---------+                    +---------+
                                          |
                                          | 调度
                                          ↓
                                      +---------+
                                      |  运行   |
                                      +---------+
                                          |
                    +---------------------+---------------------+
                    |                                           |
                等待资源                                    任务完成或终止
                    |                                           |
                    ↓                                           ↓
              +---------+                                  +---------+
              | 阻塞/等待|                                  |  终止   |
              +---------+                                  +---------+
                    |
           条件满足或资源释放
                    |
                    ↓
              +---------+
              |  就绪   |
              +---------+

线程的实现方式:

  • 内核线程
    • 由操作系统内核直接支持和管理。
    • 每个线程都有内核调度实体,切换开销大。
    • 提供更高的可靠性,但创建和上下文切换成本较高。
  • 用户线程
    • 完全在用户态实现,操作系统无法直接感知。
    • 切换速度快,但无法利用多核 CPU。
    • 适合任务切换频繁但不需要 I/O 的场景。
  • 混合线程
    • 将内核线程和用户线程结合,实现两者的优点。
    • 常见于现代操作系统。

线程同步:
由于线程共享资源,可能会引发竞争问题(Race Condition)。需要线程同步来保证数据一致性。

  • 互斥锁(Mutex):用于保护共享资源,确保同一时刻只有一个线程访问资源。
  • 读写锁(Read-Write Lock):支持多个线程同时读,但写操作需要独占锁。
  • 信号量(Semaphore):用于限制资源的并发访问数量。
  • 条件变量(Condition Variable):用于线程间的协调和通知。
  • 屏障(Barrier):用于线程同步,确保所有线程到达屏障点后才继续执行。

线程在 Linux 中的实现:

  • POSIX 线程(pthread):Linux 使用 pthread 库来实现线程,符合 POSIX 标准。
  • 内核线程:Linux 内核提供轻量级进程(LWP),通过 clone() 系统调用实现。用户态线程库如 pthread 封装了 clone 。
  • 多线程编程工具:Linux 支持多种线程编程工具,如 OpenMP、C++ 标准线程库等。

线程的优缺点:

  • 优点
    • 线程间通信高效。
    • 资源开销小,适合高并发场景。
    • 切换速度快,响应时间短。
  • 缺点
    • 资源共享可能导致数据竞争问题。
    • 一个线程崩溃可能影响整个进程。
    • 调试复杂性较高。

线程的典型应用场景:

  • Web 服务器:处理高并发请求,每个线程负责一个客户端。
  • GUI 程序:主线程负责界面渲染,工作线程负责处理后台任务。
  • 科学计算:分解任务到多个线程,提高计算效率。
  • 实时系统:多个线程并行处理实时事件。

调度

调度是操作系统的核心功能之一,用于管理系统资源(特别是 CPU)的分配,确保多任务系统中的进程或线程能够高效地运行。调度决定了进程或线程在何时、如何获取 CPU 时间以及如何切换。

调度的类型:

  • 高层调度(长程调度,Long-Term Scheduling)
    • 作用:决定哪些作业可以进入内存,成为就绪状态的进程。
    • 特点:控制系统中就绪进程的数量,以平衡 CPU 和 I/O 的利用率。在批处理系统中较为常见。
    • 触发条件:作业提交或完成时。
    • 典型任务:限制同时运行的进程数量,防止资源过载。
  • 中层调度(中程调度,Medium-Term Scheduling)
    • 作用:对已进入内存的进程进行挂起或恢复,以优化内存使用。
    • 特点:通过将部分进程换出内存(挂起)或换入内存(恢复),实现内存与 CPU 的有效利用。提高系统性能,避免资源竞争。
    • 触发条件:系统负载过高或内存紧张。
    • 典型任务:虚拟内存系统中的换页机制。
  • 低层调度(短程调度,Short-Term Scheduling)
    • 作用:决定哪个就绪进程/线程可以获得 CPU,负责具体的任务调度。
    • 特点:调度频繁,直接影响系统性能。需要高效算法,保证调度的快速响应。
    • 触发条件:时间片用完、I/O 中断、优先级变化等。
    • 典型任务:多任务系统中的 CPU 分配。

调度的目标:

  • 公平性(Fairness):确保所有进程或线程公平地获取资源。
  • 效率(Efficiency):提高资源利用率,如 CPU 和内存的利用率。
  • 响应时间(Response Time):交互式系统中,尽可能缩短任务响应的延迟。作业完成时间-作业提交时间。
  • 吞吐量(Throughput):提高单位时间内完成的任务数量。平均每秒完成的作业数量。
  • 实时性(Real-Time Capability):实时系统中,确保任务在截止时间前完成。
  • 避免饥饿(Avoid Starvation):确保低优先级任务不会无限等待。

调度在 Linux 系统中的实现:

  • 基于虚拟运行时间(vruntime):每个任务分配一个 vruntime 值,表示任务的运行时间。调度器优先选择 vruntime 最小的任务运行。
  • 红黑树存储就绪队列:任务以 vruntime 为键存储在红黑树中,实现高效插入和查找。
  • 动态优先级调整:系统根据任务的行为动态调整优先级,平衡 I/O 密集型任务和 CPU 密集型任务的资源竞争。

image

进程调度的算法

调度算法分类:

  1. 非抢占式调度
    • 特点:进程/线程一旦获得 CPU,直到主动释放或结束运行,调度器才会切换。简单但可能导致低优先级任务长时间等待。
    • 常见算法:
      • 先来先服务(FCFS):对长作业有利,对短作业不利,不会导致饥饿。
      • 最短作业优先(SJF):目前已经到达的运行时间最短的被调度。
  2. 抢占式调度
    • 特点:系统允许高优先级任务中断正在运行的任务。能更好地响应实时需求,提高系统的公平性。
    • 常见算法:
      • 时间片轮转(Round Robin)。
      • 最短剩余时间优先(SRTF)。
      • 优先级调度(Priority Scheduling)。
      • 多级队列调度(Multilevel Queue Scheduling)。

image