发布时间:2026/8/30 17:40:46
Rust 入门实战(7):并发与异步入门 上一篇的泛型仓库能替换存储实现但所有调用仍在单线程顺序执行。本篇先用线程与通道完成 CPU/阻塞工作再用 Tokio 演示异步调度解释Send、Sync、锁范围和取消安全而不是只记住.await。一、痛点并发、并行与异步不是同义词并发描述多个任务在时间上推进并行表示多个任务在多个核心同时执行异步是一种在等待时主动让出执行权的并发模型。CPU 密集计算适合线程池并行成千上万网络连接大多在等待 I/O适合异步运行时。把阻塞文件或计算直接放进异步执行器会卡住承载其他任务的工作线程。Rust 的类型系统把部分并发错误提前Send表示值可在线程间转移Sync表示共享引用可在线程间安全使用。它们多由编译器自动推导。Rc非原子计数不可跨线程Arc使用原子计数可共享所有权。共享可变状态还需Mutex或RwLock计数本身不会保护内部数据。优先消息传递生产者移动消息给消费者所有权边界简单。确实需要多个线程读写同一映射时才用ArcMutexT并尽量缩短持锁时间。二、原理线程所有权与通道背压thread::spawn闭包通常要求static用move把拥有值移入线程。通道发送端可克隆给多个生产者接收端迭代直到所有发送端释放。无界通道可能在生产快于消费时增长内存真实系统应采用有界队列或明确限流。usestd::sync::mpsc;usestd::thread;#[derive(Debug)]structResultItem{id:u32,score:u32}fnscore(id:u32)-u32{(1..id).map(|value|value*value).sum()}fnmain(){let(sender,receiver)mpsc::channel();letmuthandlesVec::new();foridin1..4{letworker_sendersender.clone();handles.push(thread::spawn(move||{letitemResultItem{id,score:score(id)};worker_sender.send(item).expect(接收端仍存在);}));}drop(sender);forhandleinhandles{handle.join().expect(工作线程不应 panic);}letmutresults:Vec_receiver.into_iter().collect();results.sort_by_key(|item|item.id);foriteminresults{println!(id{} score{},item.id,item.score);}}运行输出id1 score1 id2 score5 id3 score14 id4 score30线程完成顺序不确定所以输出前按编号排序。并发测试若依赖自然调度顺序会偶发失败稳定输出必须来自显式排序或协议保证。join不仅等待还传播线程 panic生产代码应转换为错误并决定是否继续。三、实现用 Tokio 调度等待型任务异步函数调用后返回Future只有被.await或运行时轮询才推进。等待点可能暂停当前任务因此不要跨.await长时间持有同步锁。下面项目在Cargo.toml加tokio { version 1, features [full] }每个任务模拟一次远程请求。usetokio::task::JoinSet;usetokio::time::{sleep,Duration};#[derive(Debug)]structTask{id:u32,title:staticstr}asyncfnfetch(task:Task)-String{letdelayDuration::from_millis((5-task.id)asu64*10);sleep(delay).await;format!({}:{},task.id,task.title)}#[tokio::main]asyncfnmain(){lettasks[Task{id:1,title:文档},Task{id:2,title:测试},Task{id:3,title:服务},Task{id:4,title:部署},];letmutsetJoinSet::new();fortaskintasks{set.spawn(fetch(task));}letmutvaluesVec::new();whileletSome(result)set.join_next().await{values.push(result.expect(任务不应 panic));}values.sort();forvalueinvalues{println!(result{value});}}运行输出result1:文档 result2:测试 result3:服务 result4:部署JoinSet管理一组动态任务并显式接收完成结果。直接spawn后丢弃句柄会让错误无处观察。超时可用tokio::time::timeout包裹 future但超时只停止等待底层操作是否取消、是否产生部分副作用要查具体 API 契约。四、踩坑锁、阻塞与无限制 spawn持MutexGuard做网络请求会让其他任务等待最慢 I/O。正确做法是在锁内读取或更新最小数据释放锁后再.await。标准库锁适合短且不跨等待点的临界区确需跨异步等待的锁可用 Tokio 版本但更应重新审视状态所有权。异步不自动更快。少量顺序任务使用普通阻塞代码更简单CPU 密集计算应交给专用线程池或spawn_blocking否则执行器延迟上升。无限tokio::spawn会造成连接、内存和下游压力应用信号量限制在途数量并让队列长度可观测。死锁不仅是两把锁互等也可能因任务持锁等待另一个需要同锁的任务。统一锁顺序、减少共享状态、用消息循环单独拥有状态都能降低风险。并发 bug 难靠一次运行发现设计时要明确关闭、取消、超时和错误传播路径。五、验证让非确定调度产生确定结论测试结果集合而非完成顺序时间相关测试使用 Tokio 的暂停时间能力减少真实睡眠。通道必须验证发送端关闭后消费者能退出有界队列要测试满载策略。共享计数测试应多次运行并用线程检测工具或模型检查库补充关键同步逻辑。现在任务可以并发处理并异步等待但依赖和特性还写在单一包里。下一篇转向 Cargo 工程化拆分库与二进制、使用 feature、workspace、锁文件和发布配置让后面的网络服务拥有清晰项目骨架。参考来源Rust BookFearless ConcurrencyRust 标准库std::syncTokio TutorialAsync Book异步编程 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《Rust 入门实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。

相关新闻

2026/8/30 17:40:46

Rust 入门实战(4):错误处理与 Result

上一篇的集合查询会遇到缺失键,文本解析也可能收到非法内容。本篇不再用默认值掩盖问题,而是用 Option 表示“可能没有”,用 Result 表示“可能失败”,并建立从底层原因到用户提示的错误链。 一、痛点:panic 不是普通…

2026/8/30 17:35:46

电子信息产业创新融合:从四链协同到全栈联动的路径与启示

今年电子信息领域有一个话题讨论度很高:科技创新和产业创新到底怎么“融”在一起,而不是停留在口号上。清华大学汪玉老师在 CEIC2026 上专门讲了电子信息领域科技创新与产业创新深度融合的路径,里面有不少内容值得做技术的人仔细看一遍。这篇…

2026/8/30 17:35:46

大模型人格一致性:AI人类模拟器的工程化实现指南

AI人类模拟器,价值130亿。这个标题最近被讨论得很多,但不少人的关注点落在了那个数字上。如果让我先给一句实在的判断:那个数字是否准确,我无法核实,也不影响这篇内容的判断。真正值得关注的是,用AI模拟一个…

2026/8/30 17:55:47

LSP for LLM:用标准协议将大模型接入IDE的工程实践

大模型编程助手大家已经用得很多了,可一旦你尝试把某个模型接入团队自己的 IDE 工作流,很快会遇到一个尴尬问题:模型本身不难接,难的是为每个编辑器各写一套协议。VSCode 一套插件、JetBrains 一套插件、网页编辑器再一套插件&…

2026/8/30 17:55:47

LSP for LLM:把代码结构感知接入大语言模型的关键一步

如果你现在去搜索“LSP”,大概率会同时看到三种完全不同的东西:AutoCAD 里用来自动绘制链轮的 .lsp 脚本文件,编程编辑器里常说的 Language Server Protocol,以及最近在 LLM 工具链里频繁出现的“LSP for LLM”这个组合。同一组字…

2026/8/30 17:55:47

AI+Postman:接口测试用例生成与批量回归实践

把AI用到Postman接口测试里,最大的变化不是少点几次鼠标,而是把测试设计的起点变了。以前拿到一个接口,要先看文档、写请求、想边界值、补断言,这套流程非常依赖个人经验;现在可以先把接口描述、业务规则和预期结果喂给…

2026/8/30 17:50:47

Ollama本地大模型部署实战:从安装到API调用与Agent开发

Ollama 是目前本地大模型领域最常见的运行容器。它把模型拉取、启动、调用和模型管理压缩成了几条命令,让普通开发者可以用一张消费级显卡或纯 CPU 环境,把开源大模型跑在自己机器上。如果你最近在关注 AI 大模型、Agent 开发、本地部署或者接口 API 封装…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/30 0:03:35

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/30 0:03:35

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/30 0:03:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/28 16:16:48

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/28 16:16:50

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/28 11:06:45

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…