Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. std::sync::mpsc Channel

std::sync::mpsc Channel

For inter-thread communication in Rust, use the std::sync::mpsc (multiple producer, single consumer) channel. This is a message-passing pattern where you send values from the sender (Sender) side and receive them on the receiver (Receiver) side.

Syntax

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

// Create a channel (tx: sender, rx: receiver).
let (tx, rx) = mpsc::channel();

// Send a value (tx can be cloned, so multiple threads can send).
tx.send(value).unwrap();

// Receive a value (blocks until the next message arrives).
let received = rx.recv().unwrap();

// Non-blocking receive (returns Err immediately if no message is available).
match rx.try_recv() {
    Ok(val) => println!("{}", val),
    Err(_) => println!("No message yet"),
}

// Receive all messages (loop ends when all senders are dropped).
for msg in rx {
    println!("{}", msg);
}

Method List

MethodDescription
mpsc::channel()Creates an asynchronous channel. Returns (Sender<T>, Receiver<T>).
mpsc::sync_channel(n)Creates a synchronous channel with a buffer capacity of n. Blocks on send when the buffer is full.
tx.send(val)Sends a value. Returns Err if the receiver has been dropped.
tx.clone()Clones the sender, allowing multiple threads to send on the same channel.
rx.recv()Blocks until a value is received. Returns Err when all senders have been dropped.
rx.try_recv()Attempts to receive immediately. Returns Err right away if no message is available (non-blocking).
rx.recv_timeout(dur)Receives with a timeout.
for msg in rxIterates over received messages until all senders are closed.

Sample Code

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    // --- Basic send and receive ---
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        tx.send(String::from("Hello from the thread!")).unwrap();
    });

    let msg = rx.recv().unwrap();
    println!("Received: {}", msg);

    // --- Sending and receiving multiple messages ---
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let messages = vec!["ping", "pong", "done"];
        for msg in messages {
            tx.send(msg).unwrap();
            thread::sleep(Duration::from_millis(10));
        }
        // When tx is dropped, iteration on rx ends.
    });

    for msg in rx {
        println!("Received: {}", msg);
    }

    // --- Multiple producers (the "multiple producer" in mpsc) ---
    let (tx, rx) = mpsc::channel();
    let mut handles = vec![];

    for i in 0..3 {
        let tx_clone = tx.clone();  // Clone the sender.
        let h = thread::spawn(move || {
            tx_clone.send(format!("Sender {}: data", i)).unwrap();
        });
        handles.push(h);
    }
    drop(tx);  // Close the original tx (so the rx iteration can end).

    for msg in rx {
        println!("{}", msg);
    }

    for h in handles {
        h.join().unwrap();
    }

    // --- Non-blocking receive with try_recv ---
    let (tx, rx) = mpsc::channel::<i32>();
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(50));
        tx.send(42).unwrap();
    });

    loop {
        match rx.try_recv() {
            Ok(val) => { println!("Received: {}", val); break; }
            Err(mpsc::TryRecvError::Empty) => {
                println!("Not yet...");
                thread::sleep(Duration::from_millis(20));
            }
            Err(mpsc::TryRecvError::Disconnected) => break,
        }
    }
}

Overview

mpsc::channel() creates a "multiple producer, single consumer" channel. The sender (Sender) can be cloned with clone(), allowing multiple threads to send, but the receiver (Receiver) cannot be cloned (single consumer).

When all Senders are dropped, rx.recv() returns Err and any for msg in rx loop ends. You can use this behavior to detect when worker threads have finished.

For inter-thread communication via shared memory, see Mutex<T> / RwLock<T>. For creating and waiting on threads, see std::thread::spawn() / join().

If you find any errors or copyright issues, please .