mpsc 的名字就是「多生产者、单消费者」。这篇验证多生产者之间的顺序保证、单消费者的限制与变通、忘记 drop 发送端的经典死等,以及有界通道的阻塞与吞吐量差别。
编译:成功
运行(退出码 0):
共收到 12 条
生产者 0 的序号按发送顺序到达: true
生产者 1 的序号按发送顺序到达: true
生产者 2 的序号按发送顺序到达: true
到达顺序(生产者编号): 000012111222通道的基本语义见Channel 消息传递。
编译:成功
运行(退出码 0):
Ok(1)
子线程已结束(它的 tx2 已 drop),但主线程手里的 tx 还活着:Err(Timeout)
drop(tx) 之后:Err(Disconnected) 源码:
1 | use std::sync::mpsc;
2 | fn main() { let (_tx, rx) = mpsc::channel::<i32>(); let _r2 = rx.clone(); }
编译:失败
error[E0599]: no method named `clone` found for struct `std::sync::mpsc::Receiver<T>` in the current scope
--> <实验目录>/src/u89c.rs:2:66
|
2 | fn main() { let (_tx, rx) = mpsc::channel::<i32>(); let _r2 = rx.clone(); }
| ^^^^^ method not found in `std::sync::mpsc::Receiver<i32>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0599`.
源码:
1 | use std::{sync::mpsc, thread};
2 | fn main() { let (_tx, rx) = mpsc::channel::<i32>(); thread::scope(|s| { s.spawn(|| { let _ = rx.recv(); }); s.spawn(|| { let _ = rx.recv(); }); }); }
编译:失败
error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
--> <实验目录>/src/u89d.rs:2:81
|
2 | ...ope(|s| { s.spawn(|| { let _ = rx.recv(); }); s.spawn(|| { let _ = rx.recv(); }); }); }
| ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
= note: required for `&std::sync::mpsc::Receiver<i32>` to implement `Send`
note: required because it's used within this closure
--> <实验目录>/src/u89d.rs:2:81
|
2 | fn main() { let (_tx, rx) = mpsc::channel::<i32>(); thread::scope(|s| { s.spawn(|| { let _ = rx.recv(); }); s.spawn(|| { let _ = rx...
| ^^
note: required by a bound in `Scope::<'scope, 'env>::spawn`
--> <rust 标准库源码>/library/std/src/thread/scoped.rs:203:28
|
201 | pub fn spawn<F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T>
| ----- required by a bound in this associated function
202 | where
203 | F: FnOnce() -> T + Send + 'scope,
| ^^^^ required by this bound in `Scope::<'scope, 'env>::spawn`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.Sync 的含义见Send 与 Sync。
编译:成功
运行(退出码 0):
处理了 20 个任务,每个任务恰好一次: true
4 个工作线程各处理的任务数: [5, 5, 5, 5] 编译:成功
运行(退出码 0):
容量 2:已发 2 个,try_send 第 3 个: Err(TrySendError::Full(..))
接收端睡了 100 ms 才取走一个:Ok(1)
第 3 个 send 在通道满时被阻塞了约 100 毫秒(取整到 50)
容量 0(会合):没有接收者在等时 try_send = Err(TrySendError::Full(..))
接收者在等时 send 成功,对方收到 7 编译:成功
运行(退出码 0):
unbounded 100 万条 11.7 ms(约 12 ns/条)
sync1 100 万条 2384.3 ms(约 2384 ns/条)
sync1024 100 万条 7.6 ms(约 8 ns/条)数字是本机 release 实测的最小值,只测了 1 个生产者 1 个消费者;更多线程时的竞争没有测。