w3resource

Implementing a Message Broadcast System in Rust

Rust Error Propagation: Exercise-7 with Solution

Write a Rust program to implement a message broadcast system using channels. Create one sender thread and multiple receiver threads. When the sender sends a message through the channel, all receiver threads should receive and print the message.

Sample Solution:

Rust Code:

use std::sync::{mpsc, Arc, Mutex}; // Import necessary modules for multi-threading
use std::thread; // Import necessary module for multi-threading

const NUM_RECEIVERS: usize = 3; // Define the number of receiver threads
const MESSAGE: &str = "Hello, world!"; // Define the message to be sent

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

    // Create an Arc to share ownership of the receiver across threads
    let receiver = Arc::new(Mutex::new(receiver));

    // Spawn receiver threads
    let mut handles = Vec::new(); // Create a vector to store thread handles
    for _ in 0..NUM_RECEIVERS {
        let rx = Arc::clone(&receiver); // Clone the Arc to pass to each receiver thread
        let handle = thread::spawn(move || { // Spawn a new receiver thread
            // Receive and print messages
            loop {
                match rx.lock().unwrap().recv() { // Lock the mutex and receive messages from the channel
                    Ok(msg) => println!("Received message: {}", msg), // If message received successfully, print it
                    Err(_) => break, // Break the loop if the channel is closed
                }
            }
        });
        handles.push(handle); // Store the handle of the spawned thread
    }

    // Spawn sender thread
    let sender_handle = thread::spawn(move || {
        // Send message to all receivers
        for _ in 0..NUM_RECEIVERS {
            sender.send(String::from(MESSAGE)).unwrap(); // Send the message through the channel
        }
        drop(sender); // Close the channel after sending all messages
    });

    // Wait for sender and receiver threads to finish
    sender_handle.join().unwrap(); // Wait for the sender thread to finish
    for handle in handles {
        handle.join().unwrap(); // Wait for each receiver thread to finish
    }
}

Output:

Received message: Hello, world!
Received message: Hello, world!
Received message: Hello, world!

Explanation:

In the exercise above,

  • Import modules: The code imports modules for multi-threading (std::sync::mpsc for channels and std::thread for thread management).
  • Define constants: It defines the constants 'NUM_RECEIVERS' and 'MESSAGE'. 'NUM_RECEIVERS' specifies the number of receiver threads to spawn, and 'MESSAGE' contains the message to be sent.
  • Main function:
    • Channel creation: It creates a channel for communication between sender and receiver threads.
    • Shared receiver: It wraps the receiver in an 'Arc' and 'Mutex' to allow safe sharing among multiple threads.
    • Spawn receiver threads: It spawns multiple receiver threads. Each thread locks the mutex, receives messages from the channel, and prints them until the channel is closed.
    • Spawn sender thread: It spawns a sender thread that sends the message to all receiver threads through the channel.
    • Wait for threads to finish: It waits for both sender and receiver threads to finish execution using "join()".
  • Sender thread: Sends the message to all receivers through the channel.
  • Receiver threads: Receive messages from the channel, print them, and break the loop if the channel is closed.

Rust Code Editor:

Previous: Implementing Synchronous Channels in Rust.
Next: Demonstrating Buffered Channels in Rust.

What is the difficulty level of this exercise?

Test your Programming skills with w3resource's quiz.



Become a Patron!

Follow us on Facebook and Twitter for latest update.

It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.

https://www.w3resource.com/rust/channels/rust-message-passing-exercise-7.php