Module std::sync::mpsc

1.0.0 · source ·
Expand description

多生产者,单消费者 FIFO 队列通信原语。

该模块通过通道提供基于消息的通信,具体定义为以下三种类型:

SenderSyncSender 用于将数据发送到 Receiver。 两个发送者都是可克隆的 (multi-producer),因此许多线程可以同时发送到一个接收者 (single-consumer)。

这些通道有两种口味:

  1. 异步,无限缓冲的通道。 channel 函数将返回 (Sender, Receiver) 元组,其中所有发送都是异步的 (它们从不阻塞)。 通道在概念上具有无限的缓冲区。

  2. 同步的有界通道。 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");
Run

Structs

Enums

Functions

  • 创建一个新的异步通道,返回 sender/receiver 一半。 在 Sender 上发送的所有数据将以与发送时相同的顺序在 Receiver 上可用,并且没有 send 将阻塞调用线程 (此通道具有一个 “无限缓冲区”,与 sync_channel 不同,它将在达到其缓冲区限制后阻塞)。 recv 将阻塞直到消息可用,同时至少有一个 Sender 活着 (包括克隆)。
  • 创建一个新的同步有界通道。 SyncSender 上发送的所有数据将以与发送相同的顺序在 Receiver 上可用。 像异步 channel 一样,Receiver 将阻塞直到消息可用为止。 然而,sync_channel 在发送者的语义上有很大不同。