先学清楚一份任务怎么完成
这是一份独立的项目学习专题。目标是看到 Slime 的异步代码时,能够说清:工作何时开始,谁在等待,哪些工作可以交错推进,退出时由谁收尾。
从第 1 节开始即可。 只需知道 Python 函数、参数、返回值和 try/finally;不要求先理解强化学习、Ray 或模型服务。每节先运行一个小实验,再展开对应的 Slime 源码。
01–14:先建立任务执行的主线
| 节 | 本节解决的问题 |
|---|---|
| 01 · async def:定义之后,什么时候执行? | 先分清异步函数、协程对象和真正执行的函数体。 |
| 02 · await:等待结果,不等于自动并发 | 沿执行顺序理解挂起、恢复和 asyncio.sleep。 |
| 03 · Task 与 gather:把多份工作安排起来 | 看清创建任务、保留引用和等待整组结果三个动作。 |
| 04 · wait 与 as_completed:先处理已经完成的工作 | 区分整组返回、完成集合和按完成顺序消费。 |
| 05 · 取消与超时:请求停止以后,还要等待收尾 | 理解 cancel、CancelledError、finally 和任务级超时。 |
| 06 · Semaphore:限制同时进入的工作数量 | 把并发许可与任务总量区分开。 |
| 07 · Queue:把生产速度和消费速度接起来 | 用有界队列理解等待、背压与结束信号。 |
| 08 · 线程池:把阻塞工作移出事件循环 | 理解 to_thread、run_in_executor 与两类 Future 的边界。 |
| 09 · Lock、Event 与线程退出 | 线程共享状态怎样保护,后台线程怎样收到停止信号。 |
| 10 · async with、async for 与异步生成器 | 把异步资源的进入、迭代和退出连起来。 |
| 11 · ContextVar:让并发任务保留各自的上下文 | 区分任务上下文与共享全局变量,并恢复进入前的状态。 |
| 12 · 进程池、子进程与系统边界 | 从 spawn 和 Pool.starmap 出发,区分进程、线程与 asyncio。 |
| 13 · Future、回调与跨线程事件循环 | 理解谁保存尚未完成的结果,谁负责把等待者唤醒。 |
| 14 · 回到 Slime:串起创建、等待与清理 | 用一条完整任务主线检查前面学过的原生机制。 |
15–21:补齐通知、同步与系统边界
前 14 节先把一份任务的生命周期读通,下面逐项补齐 Slime 中出现的其他原生用法。已有章节编号保持不变;也可以从源码用法与教程对照按遇到的接口直接进入。
| 节 | 本节解决的问题 |
|---|---|
| 15 · Event 通知与异步互斥 | 为什么任务已经开始,却还要等一次通知;set、wait、clear 和 Lock 分别做什么。 |
| 16 · Condition、RLock 与 Timer | 等共享条件时怎样释放锁,醒来后为什么重查,计时线程怎样结束。 |
| 17 · 线程池 Future 的结果与退出 | submit、map、wait、as_completed、取消和 shutdown 的同步合同。 |
| 18 · 进程生命周期:从队列工作到超时回收 | 多进程队列怎样传结果,完成消息与进程退出有何区别,命令超时后怎样回收。 |
| 19 · 信号、进程组与文件锁 | 信号发给谁,怎样等待管道就绪,持锁进程退出后谁释放锁。 |
| 20 · asyncio Streams | 按协议读字节、处理提前 EOF,区分写入缓冲、连接关闭和服务关闭。 |
| 21 · 异步能力检查与协议边界 | 函数检查、返回值检查、类型注解和异步协议各能说明什么。 |
每节末尾可展开该知识点对应的全部源码位置,查看原代码行,并打开固定版本的原文或完整文件快照。重复出现的接口共用解释;每个业务调用的输入与清理仍需沿所在函数核对。
源码用法与教程对照逐项连接扫描结果和讲解,也保留 Slime 文档里的 29 段 Python 示例。没有接收者类型证据的同名方法单独标为候选;它们有核对入口,但不冒称已经证明是原生并发 API。
怎样使用示例
每节的 example.py 都可以下载后用 Python 3.11 及以上版本运行。示例只使用标准库,不连接模型服务、不启动 Slime 训练。文中明确区分独立语言实验、教学裁剪和固定版本的原源码。
每次只做三件事:先猜输出,再运行,最后回答该节的复述问题。源码入口默认收起,等概念清楚后再展开;文件名、函数名、原行号与固定提交都保留。
需要回查时
原始资料仍单独保存在项目根目录 python-async-concurrency/。本专题位于网站“项目”栏目。