Rust Asynchronous Channels Communication

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, you will learn about Rust's asynchronous channels, which allow unidirectional communication between threads using the Sender and Receiver endpoints, as demonstrated in the provided Rust code snippet.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/ControlStructuresGroup(["`Control Structures`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/DataStructuresandEnumsGroup(["`Data Structures and Enums`"]) rust(("`Rust`")) -.-> rust/PerformanceandConcurrencyGroup(["`Performance and Concurrency`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/BasicConceptsGroup -.-> rust/mutable_variables("`Mutable Variables`") rust/DataTypesGroup -.-> rust/integer_types("`Integer Types`") rust/DataTypesGroup -.-> rust/string_type("`String Type`") rust/DataTypesGroup -.-> rust/type_casting("`Type Conversion and Casting`") rust/ControlStructuresGroup -.-> rust/for_loop("`for Loop`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("`Method Syntax`") rust/PerformanceandConcurrencyGroup -.-> rust/message_passing("`Message Passing`") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("`Traits for Operator Overloading`") subgraph Lab Skills rust/variable_declarations -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/mutable_variables -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/integer_types -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/string_type -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/type_casting -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/for_loop -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/function_syntax -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/expressions_statements -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/method_syntax -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/message_passing -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} rust/operator_overloading -.-> lab-99268{{"`Rust Asynchronous Channels Communication`"}} end

Channels

Rust provides asynchronous channels for communication between threads. Channels allow a unidirectional flow of information between two end-points: the Sender and the Receiver.

use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

static NTHREADS: i32 = 3;

fn main() {
    // Channels have two endpoints: the `Sender<T>` and the `Receiver<T>`,
    // where `T` is the type of the message to be transferred
    // (type annotation is superfluous)
    let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
    let mut children = Vec::new();

    for id in 0..NTHREADS {
        // The sender endpoint can be copied
        let thread_tx = tx.clone();

        // Each thread will send its id via the channel
        let child = thread::spawn(move || {
            // The thread takes ownership over `thread_tx`
            // Each thread queues a message in the channel
            thread_tx.send(id).unwrap();

            // Sending is a non-blocking operation, the thread will continue
            // immediately after sending its message
            println!("thread {} finished", id);
        });

        children.push(child);
    }

    // Here, all the messages are collected
    let mut ids = Vec::with_capacity(NTHREADS as usize);
    for _ in 0..NTHREADS {
        // The `recv` method picks a message from the channel
        // `recv` will block the current thread if there are no messages available
        ids.push(rx.recv());
    }

    // Wait for the threads to complete any remaining work
    for child in children {
        child.join().expect("oops! the child thread panicked");
    }

    // Show the order in which the messages were sent
    println!("{:?}", ids);
}

Summary

Congratulations! You have completed the Channels lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like