diff --git a/subjects/major/图论常见算法.md b/subjects/major/图论常见算法.md deleted file mode 100644 index d974685..0000000 --- a/subjects/major/图论常见算法.md +++ /dev/null @@ -1,221 +0,0 @@ -## 图论常见算法 - -### Dijkstra算法 -用于求解单个源最短路问题: - -1. 初始化:将所有顶点的距离设为正无穷,源顶点设为0; -2. 迭代:从源顶点出发,遍历所有边,更新顶点的距离; -3. 检验:检查是否存在负权重环,如果有则返回错误; -4. 返回:返回所有顶点的距离。 - - - -### Bellman-Ford算法 - -#### 数学公式 - -对于图 $G=(V,E)$,Bellman-Ford算法通过迭代松弛更新每个顶点的最短路径估计: - -$$d(v) = \min\{d(u) + w(u,v) | (u,v) \in E\}$$ - -其中: -- $d(v)$ 是从源顶点到顶点 $v$ 的最短路径估计 -- $w(u,v)$ 是边 $(u,v)$ 的权重 -- 迭代次数最多为 $|V|-1$ 次 - -#### Python实现 - -```python -def bellman_ford(graph, source): - """ - Bellman-Ford算法求单源最短路径 - - 参数: - graph: 邻接表表示的图,格式 {u: [(v, w), ...]} - source: 源顶点 - - 返回: - distances: 各顶点到源顶点的最短距离 - """ - # 初始化距离 - distances = {v: float('inf') for v in graph} - distances[source] = 0 - - # 获取所有顶点 - vertices = list(graph.keys()) - - # 最多进行 |V|-1 次迭代 - for _ in range(len(vertices) - 1): - # 对每条边进行松弛操作 - for u in graph: - for v, w in graph[u]: - if distances[u] != float('inf') and distances[u] + w < distances[v]: - distances[v] = distances[u] + w - - # 检测负权重环 - for u in graph: - for v, w in graph[u]: - if distances[u] != float('inf') and distances[u] + w < distances[v]: - raise ValueError("图中存在负权重环") - - return distances - - -# 示例使用 -if __name__ == "__main__": - # 构建图 (邻接表) - graph = { - 'A': [('B', 4), ('C', 2)], - 'B': [('C', 3), ('D', 2), ('E', 3)], - 'C': [('B', 1), ('D', 4)], - 'D': [('E', -5)], # 负权重边 - 'E': [] - } - - try: - distances = bellman_ford(graph, 'A') - print("Bellman-Ford 结果:", distances) - except ValueError as e: - print(e) -``` - ---- - -## 常用算法Python实现 - -### 1. Dijkstra算法 - -#### 数学公式 - -Dijkstra算法维护一个优先队列,每次选取具有最小距离估计的顶点: - -$$d(v) = \min_{u \in S} \{ d(u) + w(u,v) \}$$ - -其中 $S$ 是已确定最短路径的顶点集合。 - -#### Python实现 - -```python -import heapq - -def dijkstra(graph, source): - """ - Dijkstra算法求单源最短路径 - - 参数: - graph: 邻接表表示的图,格式 {u: [(v, w), ...]} - source: 源顶点 - - 返回: - distances: 各顶点到源顶点的最短距离 - """ - # 初始化距离 - distances = {v: float('inf') for v in graph} - distances[source] = 0 - - # 优先队列: (距离, 顶点) - pq = [(0, source)] - visited = set() - - while pq: - # 取出最小距离的顶点 - current_dist, u = heapq.heappop(pq) - - # 如果已访问则跳过 - if u in visited: - continue - visited.add(u) - - # 更新邻接顶点的距离 - for v, w in graph.get(u, []): - if v not in visited and current_dist + w < distances[v]: - distances[v] = current_dist + w - heapq.heappush(pq, (distances[v], v)) - - return distances - - -# 示例使用 -if __name__ == "__main__": - # 构建图 (邻接表) - graph = { - 'A': [('B', 4), ('C', 2)], - 'B': [('C', 3), ('D', 2), ('E', 3)], - 'C': [('B', 1), ('D', 4)], - 'D': [('E', 5)], - 'E': [] - } - - distances = dijkstra(graph, 'A') - print("Dijkstra 结果:", distances) - # 输出: {'A': 0, 'B': 3, 'C': 2, 'D': 5, 'E': 8} -``` - -### 2. Bellman-Ford算法 - -#### 数学公式 - -对于图 $G=(V,E)$,Bellman-Ford算法通过迭代松弛更新每个顶点的最短路径估计: - -$$d(v) = \min\{d(u) + w(u,v) | (u,v) \in E\}$$ - -其中: -- $d(v)$ 是从源顶点到顶点 $v$ 的最短路径估计 -- $w(u,v)$ 是边 $(u,v)$ 的权重 -- 迭代次数最多为 $|V|-1$ 次 - -#### Python实现 - -```python -def bellman_ford(graph, source): - """ - Bellman-Ford算法求单源最短路径 - - 参数: - graph: 邻接表表示的图,格式 {u: [(v, w), ...]} - source: 源顶点 - - 返回: - distances: 各顶点到源顶点的最短距离 - """ - # 初始化距离 - distances = {v: float('inf') for v in graph} - distances[source] = 0 - - # 获取所有顶点 - vertices = list(graph.keys()) - - # 最多进行 |V|-1 次迭代 - for _ in range(len(vertices) - 1): - # 对每条边进行松弛操作 - for u in graph: - for v, w in graph[u]: - if distances[u] != float('inf') and distances[u] + w < distances[v]: - distances[v] = distances[u] + w - - # 检测负权重环 - for u in graph: - for v, w in graph[u]: - if distances[u] != float('inf') and distances[u] + w < distances[v]: - raise ValueError("图中存在负权重环") - - return distances - - -# 示例使用 -if __name__ == "__main__": - # 构建图 (邻接表) - graph = { - 'A': [('B', 4), ('C', 2)], - 'B': [('C', 3), ('D', 2), ('E', 3)], - 'C': [('B', 1), ('D', 4)], - 'D': [('E', -5)], # 负权重边 - 'E': [] - } - - try: - distances = bellman_ford(graph, 'A') - print("Bellman-Ford 结果:", distances) - except ValueError as e: - print(e) -``` diff --git a/subjects/os/01_进程管理.md b/subjects/os/01_进程管理.md new file mode 100644 index 0000000..e1a6ed4 --- /dev/null +++ b/subjects/os/01_进程管理.md @@ -0,0 +1,188 @@ +# 进程管理 + +## 1. 进程的组成 + +**进程(Process)** 是程序在一个数据集合上的一次执行过程,是系统进行资源分配和调度的基本单位。 + +进程的组成包括: + +- **程序代码**:描述进程所要完成的功能 +- **数据集**:程序在执行时所需要的数据和工作区 +- **进程控制块(PCB)**:**进程存在的唯一标志**,包含以下信息: + - 进程标识符(PID) + - 进程状态 + - 进程优先级 + - CPU现场保护区(寄存器、程序计数器等) + - 内存管理信息(页表/段表指针) + - I/O状态信息 + - 记账信息 + - 调度信息 + +## 2. 进程内存映像 + +进程的内存空间布局(内存映像)从低地址到高地址依次为: + +| 区域 | 说明 | +|------|------| +| **代码段(Text)** | 存放可执行代码,通常只读 | +| **数据段(Data)** | 存放已初始化的全局变量和静态变量 | +| **BSS段** | 存放未初始化的全局变量和静态变量(初始化为0) | +| **堆(Heap)** | 动态分配内存,向上增长 | +| **共享库** | 共享代码和数据 | +| **栈(Stack)** | 存放函数调用、局部变量,向下增长 | +| **环境/命令行参数** | 环境变量和命令行参数 | + +## 3. 进程状态和转换 + +### 三状态模型 + +```mermaid +stateDiagram-v2 + [*] --> 就绪: 创建 + 就绪 --> 运行: 调度 + 运行 --> 就绪: 时间片用完 + 运行 --> 阻塞: 等待事件 + 阻塞 --> 就绪: 事件完成 + 运行 --> [*]: 终止 +``` + +- **创建态(New)**:进程正在被创建 +- **就绪态(Ready)**:已获得除CPU外的所有资源,等待CPU +- **运行态(Running)**:正在CPU上执行 +- **阻塞态(Blocked/Waiting)**:因等待I/O或其他资源而暂停 +- **终止态(Terminated)**:进程执行完毕 + +### 五状态模型 + +```mermaid +stateDiagram-v2 + [*] --> 创建: 新建进程 + 创建 --> 就绪: 初始化完成 + 就绪 --> 运行: 调度 + 运行 --> 就绪: 时间片用完 + 运行 --> 阻塞: 等待事件 + 阻塞 --> 就绪: 事件完成 + 运行 --> 终止: 退出 + 终止 --> [*]: 释放资源 +``` + +在基本三状态基础上增加: +- **创建态**:分配PCB,初始化资源 +- **终止态**:释放资源,保留PCB + +### 七状态模型 + +```mermaid +stateDiagram-v2 + [*] --> 创建: 新建进程 + 创建 --> 就绪挂起: 创建完成 + 创建 --> 就绪: 直接调入内存 + + 就绪挂起 --> 就绪: 激活 + 就绪 --> 就绪挂起: 挂起 + + 就绪 --> 运行: 调度 + 运行 --> 就绪: 时间片用完 + 运行 --> 阻塞: 等待事件 + 阻塞 --> 就绪: 事件完成 + + 阻塞 --> 阻塞挂起: 挂起 + 阻塞挂起 --> 阻塞: 激活 + + 运行 --> 终止: 退出 + 终止 --> [*]: 释放资源 +``` + +在五状态基础上增加挂起状态: +- **就绪挂起**:在外存,准备调入内存 +- **阻塞挂起**:在外存,等待事件完成 + +## 4. 进程的通信 + +进程间通信(IPC,Inter-Process Communication)主要有以下方式: + +### 4.1 高级通信方式 + +| 方式 | 说明 | +|------|------| +| **管道(Pipe)** | 半双工,用于父子/兄弟进程间通信 | +| **命名管道(FIFO)** | 无亲缘关系的进程也可通信 | +| **消息队列** | 消息链表,按类型优先級排队 | +| **共享内存** | 多个进程共享同一块内存区域(最快) | +| **信号量** | 计数器,用于进程同步 | +| **套接字(Socket)** | 可用于不同主机间进程通信 | + +### 4.2 低级通信方式 + +- **信号(Signal)**:异步通知机制 + +### 4.3 通信机制比较 + +| 机制 | 效率 | 适用场景 | +|------|------|----------| +| 共享内存 | 最高 | 频繁数据交换 | +| 管道/消息队列 | 中等 | 少量数据、顺序访问 | +| 信号量 | 快 | 同步控制 | + +## 5. 线程与多线程模型 + +### 5.1 线程的概念 + +**线程(Thread)** 是CPU调度的基本单位,是进程中的一个执行流。同一个进程中的线程共享进程的地址空间和资源。 + +### 5.2 线程与进程的区别 + +| 特征 | 进程 | 线程 | +|------|------|------| +| 资源拥有 | 独立资源 | 共享进程资源 | +| 调度单位 | 进程 | 线程 | +| 地址空间 | 独立地址空间 | 共享地址空间 | +| 开销 | 大(创建/切换开销大) | 小(轻量级) | +| 通信 | 需要IPC | 直接读写共享数据 | +| 独立性 | 独立 | 依赖进程 | + +### 5.3 线程的组成 + +每个线程拥有: +- **线程ID** +- **程序计数器(PC)** +- **寄存器集合** +- **栈** + +线程共享: +- **代码段、数据段** +- **堆** +- **文件描述符** +- **信号处理器** +- **当前工作目录** +- **用户ID/组ID** + +### 5.4 多线程模型 + +| 模型 | 说明 | 优点 | 缺点 | +|------|------|------|------| +| **多对一** | 多个用户线程映射到一个内核线程 | 效率高 | 一个线程阻塞导致整个进程阻塞 | +| **一对一** | 每个用户线程映射到一个内核线程 | 并发性好 | 线程创建开销大,受限内核线程数 | +| **多对多** | 多个用户线程映射到多个内核线程 | 综合两者优点 | 实现复杂 | + +### 5.5 线程的状态 + +线程状态与进程类似: +- **就绪**:已准备好运行 +- **运行**:正在CPU执行 +- **阻塞**:等待资源或事件 +- **终止**:执行完毕 + +### 5.6 线程的实现方式 + +1. **用户线程(User Thread)**:内核不知道线程存在,线程库管理 +2. **内核线程(Kernel Thread)**:OS直接支持,内核管理 +3. **轻量级进程(LWP)**:一对一模型中的中间层 + +--- + +> **核心要点**: +> - PCB是进程存在的唯一标志 +> - 进程是资源分配单位,线程是CPU调度单位 +> - 线程共享进程资源,创建/切换开销小 +> - 进程通信需要IPC,线程间可直接通信