Skip to content

Commit c6ba64d

Browse files
authored
Create kaist-cs492-3.md
1 parent b81ef13 commit c6ba64d

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

content/Blog/kaist-cs492-3.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
Title: KAIST CS492 - 并发编程 · 课程速读(Part3. 作业1 - 并行Web服务器)
2+
Date: 2025-10-07 10:00
3+
Tags: 并行计算, 并发, Rust, 系统编程
4+
Slug: kaist-cs492-3
5+
6+
[课程主页](https://github.com/kaist-cp/cs431)
7+
8+
## 作业 1:**并行 Web 服务器(Parallel Web Server)**
9+
10+
在这一节课中,课程正式布置了第一个编程作业——实现一个“并行 Web 服务器”。这个作业不仅是对并发与线程管理的实践练习,也是对课程前面关于锁、线程、共享内存和同步机制理解的首次综合应用。
11+
12+
---
13+
14+
## 一、作业目标
15+
16+
你的任务是用 **Rust** 实现一个可以同时处理多个请求的并行 Web 服务器。这个服务器能够:
17+
18+
1. 监听本地端口(默认 7878);
19+
2. 响应浏览器访问请求;
20+
3. 对请求执行“耗时计算”,并将结果缓存;
21+
4. 支持多线程并行处理;
22+
5. 能够优雅地终止(当按下 Ctrl+C 时,打印访问统计信息)。
23+
24+
通过这个作业,你将学习如何将**多线程、通道通信、任务调度和缓存机制**组合起来,构建一个真正的并行程序。
25+
26+
---
27+
28+
## 二、运行方式与预期行为
29+
30+
课程提供了作业框架。编译并运行服务器:
31+
32+
```
33+
cargo run -- hello-server
34+
```
35+
36+
程序启动后,会输出启动日志。当你打开浏览器并访问以下地址:
37+
38+
```
39+
http://localhost:7878/
40+
```
41+
42+
如果访问根目录,会得到一个错误页面;
43+
如果访问某个用户名(例如 `http://localhost:7878/alice`),程序会执行一次“昂贵的计算”(模拟服务器负载),几秒钟后返回结果。之后再次访问相同页面,响应将立即返回——因为结果被缓存了。
44+
45+
访问不同的用户(如 `bob`)时,服务器会再次计算一次,然后也缓存结果。
46+
47+
按下 **Ctrl + C** 退出服务器后,程序会打印出访问统计,例如:
48+
49+
```
50+
Statistics:
51+
/alice visited 7 times
52+
/bob visited 5 times
53+
/error visited 4 times
54+
```
55+
56+
这表示服务器在运行期间记录了每个页面的访问次数。
57+
58+
---
59+
60+
## 三、系统结构概览
61+
62+
该 Web 服务器由多个线程协同组成,每个线程负责不同功能。整体结构包括:
63+
64+
1. **主线程(Main Thread)**
65+
负责创建各个组件(线程池、监听器、通道等)并启动系统。
66+
67+
2. **监听线程(Listener)**
68+
通过 TCP 监听端口,接收来自客户端的连接请求。
69+
70+
3. **工作线程(Worker Threads)**
71+
来自线程池(Thread Pool),负责处理具体请求任务。
72+
73+
4. **报告线程(Reporter)**
74+
接收各个请求处理结果,并汇总访问统计。
75+
76+
5. **取消机制(Cancelable Listener)**
77+
通过原子变量(AtomicBool)实现安全终止,当按下 Ctrl+C 时,所有线程能有序退出。
78+
79+
这些线程之间通过 **通道(Channel)** 通信,实现消息传递与同步。Rust 使用 `crossbeam` crate 提供的有界与无界通道实现高效并发通信。
80+
81+
---
82+
83+
## 四、需要你实现的部分
84+
85+
虽然框架代码已经提供了主要逻辑,但你需要亲手完成三个关键组件:
86+
87+
### 1. Cache:结果缓存模块
88+
89+
缓存是一个简单的键值存储,用于避免重复计算。
90+
91+
**功能要求:**
92+
93+
* 提供 `get_or_insert_with()` 接口;
94+
* 若 key 已存在,直接返回缓存结果;
95+
* 若不存在,则执行传入的函数(模拟昂贵计算),并将结果存入缓存后返回;
96+
* 要确保多线程环境下的安全访问(可使用互斥锁或并发结构)。
97+
98+
该模块考验你对**共享可变状态和锁机制**的理解。
99+
100+
---
101+
102+
### 2. Cancelable TCP Listener:可取消的监听器
103+
104+
Rust 标准库提供了 `TcpListener`,但你需要在其基础上实现一个可取消版本。
105+
106+
**功能要求:**
107+
108+
* 拥有与标准 `TcpListener` 相同的接口;
109+
* 增加一个 `cancel()` 方法,当调用后,所有正在阻塞的 `accept()` 调用必须被唤醒并退出;
110+
* 使用一个 `AtomicBool` 变量表示监听器是否被取消;
111+
* 调用 `cancel()` 时使用 **Release** 内存序;
112+
* 调用 `next()`(即 `accept()`)时使用 **Acquire** 内存序;
113+
* 如果监听器被取消,`next()` 应返回 `None`
114+
* 需实现唤醒机制,让被阻塞的监听线程及时检测到取消信号。
115+
116+
这部分是作业中最具技术含量的部分之一,它结合了**原子操作、内存模型****线程同步**,为后续课程打下基础。
117+
118+
---
119+
120+
### 3. Thread Pool:线程池实现
121+
122+
线程池管理一组可复用的工作线程。与直接创建新线程相比,它能显著提升性能。
123+
124+
**功能要求:**
125+
126+
* 支持创建固定大小的线程池;
127+
* 提供 `execute()` 方法提交任务;
128+
* 提供 `join()` 方法等待所有任务完成;
129+
* 使用通道在主线程与工作线程之间分发任务;
130+
* 在实现中维护一个“正在执行任务的计数器”,当任务数归零时 `join()` 才能返回。
131+
132+
Rust 官方文档与《The Rust Book》中都有类似实现,可以参考其思想,但需要根据课程框架适当调整。
133+
134+
---
135+
136+
## 五、关键技术要点
137+
138+
1. **并行与异步的区别**
139+
本作业是并行程序,不使用异步框架(如 tokio)。并行通过线程实现;异步则是通过任务调度器模拟并发。
140+
141+
2. **通道通信(Channels)**
142+
所有线程间通信都基于消息传递而非共享内存,从而避免显式锁竞争。
143+
144+
3. **原子操作与内存序(Memory Ordering)**
145+
Release/Acquire 模型保证取消信号在多核环境下的正确传播。
146+
147+
4. **线程生命周期与 join 逻辑**
148+
合理设计线程退出机制,防止僵尸线程或提前释放。
149+
150+
---
151+
152+
## 六、实现建议
153+
154+
* 从最简单的模块开始(如 Cache);
155+
* 在实现 Cancelable Listener 时,重点理解 **AtomicBool** 的使用;
156+
* Thread Pool 可参考官方文档中的示例,关注任务分发与 join 实现;
157+
* 利用 `cargo test` 验证各部分功能;
158+
* 完成后,用浏览器实际访问页面测试缓存与并行行为。
159+
160+
---
161+
162+
## 七、总结
163+
164+
这个作业不仅是一次代码练习,更是一次系统设计的训练。它让你体会到:
165+
166+
* 并发程序的结构化设计;
167+
* 多线程之间的协作与通信;
168+
* Rust 类型系统在安全并发中的作用;
169+
* 从共享内存到消息传递的编程哲学转变。
170+
171+
最终,你将得到一个真正“并行”的 Web 服务器——
172+
一个能同时响应多个请求、具备缓存能力、并能优雅关闭的高性能程序。
173+
174+
这正是现代并发系统设计的缩影。
175+
176+
> AI生成的[示例代码](https://github.com/Wizmann/KAIST-CS492/tree/main/hw01),与题目要求功能类似,细节可能有差异

0 commit comments

Comments
 (0)