Code blocks forever when receiving


#1

Following code blocks forever at receiver.

use std::collections::HashMap;
use std::sync::mpsc;
use std::thread;

pub fn frequency(values: &[&str]) -> HashMap<char, u32> {
    let input = values
        .iter()
        .filter(|x| x.len() > 0)
        .map(|x| String::from(x.clone()))
        .inspect(|x| println!("{}", x))
        .collect::<Vec<String>>();
    let (rtx, rrx) = mpsc::channel();
    for string in input {
        let mut thread_rtx = rtx.clone();
        thread::spawn(move || {
            thread_rtx
                .send(
                    string
                        .chars()
                        .filter(|x| x.is_ascii_alphabetic())
                        .map(|x| x.to_ascii_lowercase())
                        .fold(HashMap::new(), |mut acc, x| {
                            *acc.entry(x).or_insert(0) += 1;
                            acc
                        }),
                )
                .unwrap();
        });
    }
    let mut chars = HashMap::new();
    for chmap in rrx {
        chars.extend(chmap);
    }
    chars
}

Can’t understand why. Only thing I know is, if i don’t clone sender it works fine.


#2

You need to drop the original rtx once you’re done cloning it for child threads:

drop(rtx);
let mut chars = HashMap::new();
for chmap in rrx {
     chars.extend(chmap);
}
chars

Otherwise, the main thread keeps rtx alive because it’s waiting (iterating over) on the channel, but the channel is kept alive by rtx being alive.


#3

Thanks @vitalyd worked like charm.
I was trying to do rtx.drop() but kept getting error.