Multiple producer / Multiple consumer using crossbeam : Am I doing it right?

  • Multiple producer / Multiple consumer using crossbeam : Am I doing it right?
  • Is there a way to do it more concisely?
//////////////////////////////////////
// Mutiple producer - mutiple consumer
//////////////////////////////////////


use crossbeam_channel::bounded;


fn main() {

    use crossbeam_utils::thread::scope;
    
    let (s, r) = bounded(0);
    let (s1, r1) = (s.clone(), r.clone());    

    
    scope(|scope| {
        
        // Sender 1
        scope.spawn(|_| {
            for i in 0..2 {
                // println!("sending [1]: {}", i);
                s.send(i).unwrap();
            }
            drop(s);
        });

        // Sender 2
        scope.spawn(|_| {
            for i in 0..2 {
                // println!("sending [2]:{}", i);
                s1.send(i).unwrap();
            }
            drop(s1);
        });
    
        // Consumer 1
        scope.spawn(|_| {
            loop {
                let  x = r.recv();
                match x { 
                    Ok(x) => println!("1: x = {}", x),
                    Err(_) => {
                        println!("C1: All items received"); 
                        break;
                    },
                }
            }
        });

        // Consumer 2
        scope.spawn(|_| {
            loop {
                let  x = r1.recv();
                match x { 
                    Ok(x) => println!("2: y = {}", x),
                    Err(_) => {
                        println!("C2: All items received"); 
                        break;
                    },
                }
            }
        });

    }).unwrap();
}

It seems reasonable, but this syntax would be more concise:

while let Ok(msg) = r1.recv() {
    println!("2: y = {}", x);
}
println!("C2: All items received");
1 Like

Thank you ! (I'm still relatively new to Rust...) :wink:

Coded this way, it comes close to the conciseness of Go:

//////////////////////////////////////
// Mutiple producer - mutiple consumer
//////////////////////////////////////

use crossbeam_channel::bounded;

fn main() {
    use crossbeam_utils::thread::scope;

    let (s, r) = bounded(0);
    let s1 = s.clone();

    scope(|scope| {    
        // Sender 1
        scope.spawn(|_| {
            for i in 0..2 {
                s.send(i).unwrap();
            }
            drop(s);
        });

        // Sender 2
        scope.spawn(|_| {
            for i in 0..2 {
                s1.send(i).unwrap();
            }
            drop(s1);
        });

        // Consumer 1
        scope.spawn(|_| {
            while let Ok(x) = r.recv() {
                println!("x = {}", x);
            }
        });

        // Consumer 2
        scope.spawn(|_| {
            while let Ok(x) = r.recv() {
                println!("y = {}", x);
            }
        });
    })
    .unwrap();
}

You can do that even more concisely using a for loop, because Receiver impls IntoIterator:

for msg in r1 {
    println!("2: y = {}", x);
}
println!("C2: All items received");
1 Like

Super, even more Golang-ish....!