← [ BACK_TO_NOTES ]

Rust channel

std::sync::mpsc 消息传递:发送所有权、接收阻塞、多生产者与关闭语义。

#concept #growing #dev #rust

[!info] related notes

Rust channel

这个概念为什么出现

“不要通过共享内存通信,而要通过通信共享内存。”
channel 把数据的所有权发送到另一线程,降低共享可变状态。

[!abstract] 一句话理解 mpsc::channel 提供发送端/接收端;send 转移消息所有权;所有发送端 drop 后,接收端读完缓冲消息才结束迭代。

最小可运行示例

场景:日志收集——工作线程上报事件,主线程打印

多个 worker 发送日志字符串,主线程统一写出口。

use std::sync::mpsc;
use std::thread;

// 业务意图:多生产者上报日志,单消费者打印。
// 教学点:clone sender;recv 循环;sender drop 结束。

fn main() {
    let (tx, rx) = mpsc::channel::<String>();
    let mut handles = Vec::new();
    for i in 0..3 {
        let tx = tx.clone();
        handles.push(thread::spawn(move || {
            tx.send(format!("event from worker {i}"))
        }));
    }
    drop(tx); // 丢掉原始 sender,否则 rx 不结束

    for msg in rx {
        println!("log={msg}");
    }
    for handle in handles {
        handle.join().expect("worker panicked").expect("receiver closed");
    }
}

建议运行:cargo run

期望:三行 worker 日志(顺序不定)。

结合场景再看三个关注点

  1. 消息 move 到接收方
  2. 所有 sender drop 且缓冲排空后 rx 迭代结束;join 另行确认生产线程正常结束
  3. 同步 channel 背压 vs 异步 channel 生态差异

核心概念与准确模型

  • Sender/Receiver
  • send/recv/try_recv
  • channel 无界,send 不因缓冲满而等待;sync_channel(bound) 有界,满时 send 阻塞,bound=0 为双方 rendezvous
  • 有界指队列消息数量,不是总字节数;需另限制单条大小与等待中的生产者
  • 关闭:全部 sender drop

SendError 表示接收端已断开,并保留未发送的消息;RecvError 表示发送端全断开且无剩余消息。try_recv 还区分 Empty 与 Disconnected。send 返回 Ok 不等于消费者已处理或持久化消息。

设计动机

  • 所有权转移 = 清晰的数据主人
  • 减少锁竞争面
  • 组合流水线

边界与误区

  • 忘记 drop 额外 sender 导致死等
  • 无界队列内存膨胀
  • 需要广播/多消费者时换生态 crate

[!warning] 常见误区:假设 mpsc 保留发送顺序跨多线程总是“全局公平” 单 sender 有序;多 sender 交织。

工程实践

  1. 明确消息类型与关闭协议
  2. 有界 channel 控背压
  3. 错误处理不要全 unwrap
  4. 复杂图用成熟库(crossbeam/tokio::sync)

本节总结

  • 消息传递转移所有权
  • mpsc 基础模型
  • 与共享状态互补

自测题

  1. 为什么示例要 drop(tx)?
  2. channel 如何帮助避免数据竞争?
参考答案
  1. 否则仍有 sender 存活,rx 迭代不结束。
  2. 非 Copy 消息按值移动使发送方不能继续使用原值;若消息内部含 Arc 等共享句柄,底层数据仍需遵守同步规则。

延伸阅读与资料来源

资料类型支撑内容
The Book — Message Passing官方书channel
std::sync::mpsc标准库API
创建于 2026/7/15 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本