Expand description
多生产者,单消费者 FIFO 队列通信原语。
该模块通过通道提供基于消息的通信,具体定义为以下三种类型:
Sender
或 SyncSender
用于将数据发送到 Receiver
。
两个发送者都是可克隆的 (multi-producer),因此许多线程可以同时发送到一个接收者 (single-consumer)。
这些通道有两种口味:
-
异步,无限缓冲的通道。
channel
函数将返回(Sender, Receiver)
元组,其中所有发送都是异步的 (它们从不阻塞)。 通道在概念上具有无限的缓冲区。 -
同步的有界通道。
sync_channel
函数将返回(SyncSender, Receiver)
元组,其中待处理消息的存储是固定大小的预分配缓冲区。 所有的发送都将被阻塞,直到有可用的缓冲区空间。 请注意,允许的界限为 0,从而使通道成为 “rendezvous” 通道,每个发送者在该通道上原子地将消息传递给接收者。
Disconnection
通道上的发送和接收操作都将返回 Result
,指示该操作是否成功。
不成功的操作通常通过将其丢弃在相应线程中来指示具有 “hung up” 的通道的另一半。
释放通道的一半后,大多数操作将不再继续进行,因此将返回 Err
。
许多应用程序将继续对该模块返回的结果进行 unwrap
处理,如果一个线程意外死亡,则会导致线程之间传播失败。
Examples
简单用法:
use std::thread;
use std::sync::mpsc::channel;
// 创建一个简单的流通道
let (tx, rx) = channel();
thread::spawn(move|| {
tx.send(10).unwrap();
});
assert_eq!(rx.recv().unwrap(), 10);
Run共享用法:
use std::thread;
use std::sync::mpsc::channel;
// 创建一个可以从许多线程一起发送的共享通道,其中 tx 是发送一半 (用于传输的 tx),rx 是接收一半 (用于接收的 rx)。
//
//
let (tx, rx) = channel();
for i in 0..10 {
let tx = tx.clone();
thread::spawn(move|| {
tx.send(i).unwrap();
});
}
for _ in 0..10 {
let j = rx.recv().unwrap();
assert!(0 <= j && j < 10);
}
Run传播 panics:
use std::sync::mpsc::channel;
// 调用 recv() 将返回错误,因为通道已挂起 (或已释放)
//
let (tx, rx) = channel::<i32>();
drop(tx);
assert!(rx.recv().is_err());
Run同步通道:
use std::thread;
use std::sync::mpsc::sync_channel;
let (tx, rx) = sync_channel::<i32>(0);
thread::spawn(move|| {
// 这将等待父线程开始接收
tx.send(53).unwrap();
});
rx.recv().unwrap();
Run无限接收循环:
use std::sync::mpsc::sync_channel;
use std::thread;
let (tx, rx) = sync_channel(3);
for _ in 0..3 {
// 这里没有线程和克隆也是一样的,因为仍然会剩下一个 `tx`。
//
let tx = tx.clone();
// 克隆的 tx 丢弃在线程中
thread::spawn(move || tx.send("ok").unwrap());
}
// 删除最后一个发送者停止 `rx` 等待消息。
// 如果我们将其注释掉,程序将无法完成。
// 所有需要为 `rx` 排除 `tx` 才能拥有 `Err`。
drop(tx);
// 无限接收者等待所有发送者完成。
while let Ok(msg) = rx.recv() {
println!("{msg}");
}
println!("completed");
RunStructs
- Rust 的
channel
(或sync_channel
) 类型的接收一半。 这一半只能由一个线程拥有。 - 从 通道 上的
Sender::send
或SyncSender::send
函数返回错误。 - Rust 的异步
channel
类型的发送一半。 这一半只能由一个线程拥有,但可以克隆以发送给其他线程。 - Rust 的同步
sync_channel
类型的发送一半。
Enums
- 此枚举是
try_send
方法可能的错误结果的列表。
Functions
- 创建一个新的同步有界通道。
SyncSender
上发送的所有数据将以与发送相同的顺序在Receiver
上可用。 像异步channel
一样,Receiver
将阻塞直到消息可用为止。 然而,sync_channel
在发送者的语义上有很大不同。