# Module std::sync::mpsc

1.0.0 · source ·
Expand description

Multi-producer, single-consumer FIFO queue communication primitives.

This module provides message-based communication over channels, concretely defined among three types:

- `Sender`
- `SyncSender`
- `Receiver`

A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both senders are clone-able (multi-producer) such that many threads can send simultaneously to one receiver (single-consumer).

These channels come in two flavors:

1. An asynchronous, infinitely buffered channel. The `channel` function will return a `(Sender, Receiver)` tuple where all sends will be asynchronous (they never block). The channel conceptually has an infinite buffer.

2. A synchronous, bounded channel. The `sync_channel` function will return a `(SyncSender, Receiver)` tuple where the storage for pending messages is a pre-allocated buffer of a fixed size. All sends will be synchronous by blocking until there is buffer space available. Note that a bound of 0 is allowed, causing the channel to become a “rendezvous” channel where each sender atomically hands off a message to a receiver.

### Disconnection

The send and receive operations on channels will all return a `Result` indicating whether the operation succeeded or not. An unsuccessful operation is normally indicative of the other half of a channel having “hung up” by being dropped in its corresponding thread.

Once half of a channel has been deallocated, most operations can no longer continue to make progress, so `Err` will be returned. Many applications will continue to `unwrap` the results returned from this module, instigating a propagation of failure among threads if one unexpectedly dies.

## Examples

Simple usage:

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

    // Create a simple streaming channel
    let (tx, rx) = channel();
    thread::spawn(move|| {
        tx.send(10).unwrap();
    });
    assert_eq!(rx.recv().unwrap(), 10);

Run

Shared usage:

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

    // Create a shared channel that can be sent along from many threads
    // where tx is the sending half (tx for transmission), and rx is the receiving
    // half (rx for receiving).
    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

Propagating panics:

    use std::sync::mpsc::channel;

    // The call to recv() will return an error because the channel has already
    // hung up (or been deallocated)
    let (tx, rx) = channel::<i32>();
    drop(tx);
    assert!(rx.recv().is_err());

Run

Synchronous channels:

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

    let (tx, rx) = sync_channel::<i32>(0);
    thread::spawn(move|| {
        // This will wait for the parent thread to start receiving
        tx.send(53).unwrap();
    });
    rx.recv().unwrap();

Run

Unbounded receive loop:

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

    let (tx, rx) = sync_channel(3);

    for _ in 0..3 {
        // It would be the same without thread and clone here
        // since there will still be one `tx` left.
        let tx = tx.clone();
        // cloned tx dropped within thread
        thread::spawn(move || tx.send("ok").unwrap());
    }

    // Drop the last sender to stop `rx` waiting for message.
    // The program will not complete if we comment this out.
    // **All** `tx` needs to be dropped for `rx` to have `Err`.
    drop(tx);

    // Unbounded receiver waiting for all senders to complete.
    while let Ok(msg) = rx.recv() {
        println!("{msg}");
    }

    println!("completed");

Run

## Structs

- IntoIter
  An owning iterator over messages on a `Receiver`, created by `into_iter`.
- Iter
  An iterator over messages on a `Receiver`, created by `iter`.
- Receiver
  The receiving half of Rust’s `channel` (or `sync_channel`) type. This half can only be owned by one thread.
- RecvError
  An error returned from the `recv` function on a `Receiver`.
- SendError
  An error returned from the `Sender::send` or `SyncSender::send` function on channels.
- Sender
  The sending-half of Rust’s asynchronous `channel` type.
- SyncSender
  The sending-half of Rust’s synchronous `sync_channel` type.
- TryIter
  An iterator that attempts to yield all pending values for a `Receiver`, created by `try_iter`.

## Enums

- RecvTimeoutError
  This enumeration is the list of possible errors that made `recv_timeout` unable to return data when called. This can occur with both a `channel` and a `sync_channel`.
- TryRecvError
  This enumeration is the list of the possible reasons that `try_recv` could not return data when called. This can occur with both a `channel` and a `sync_channel`.
- TrySendError
  This enumeration is the list of the possible error outcomes for the `try_send` method.

## Functions

- channel
  Creates a new asynchronous channel, returning the sender/receiver halves. All data sent on the `Sender` will become available on the `Receiver` in the same order as it was sent, and no `send` will block the calling thread (this channel has an “infinite buffer”, unlike `sync_channel`, which will block after its buffer limit is reached). `recv` will block until a message is available while there is at least one `Sender` alive (including clones).
- sync_channel
  Creates a new synchronous, bounded channel. All data sent on the `SyncSender` will become available on the `Receiver` in the same order as it was sent. Like asynchronous `channel`s, the `Receiver` will block until a message becomes available. `sync_channel` differs greatly in the semantics of the sender, however.