Channel Synchronization in Rust

We can use channels to synchronize execution across threads. Here’s an example of using a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a JoinHandle.

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

// This is the function we'll run in a separate thread. The
// `tx` sender will be used to notify another thread that 
// this function's work is done.
fn worker(tx: mpsc::Sender<bool>) {
    print!("working...");
    thread::sleep(Duration::from_secs(1));
    println!("done");

    // Send a value to notify that we're done.
    tx.send(true).unwrap();
}

fn main() {
    // Create a channel for communication
    let (tx, rx) = mpsc::channel();

    // Start a worker thread, giving it the sender to notify on.
    thread::spawn(move || worker(tx));

    // Block until we receive a notification from the
    // worker on the channel.
    rx.recv().unwrap();
}

To run the program:

$ cargo run
working...done

If you removed the rx.recv().unwrap(); line from this program, the program would exit before the worker even started.

In this Rust version:

  1. We use std::thread for threading instead of goroutines.
  2. We use mpsc::channel() to create a channel for communication between threads.
  3. The worker function takes a Sender instead of a channel.
  4. We use thread::spawn to start a new thread instead of using the go keyword.
  5. We use tx.send(true) to send a value on the channel, and rx.recv().unwrap() to receive it.

This example demonstrates how to use channels for basic thread synchronization in Rust, which is conceptually similar to the original example.