Search code examples
multithreadingrustiterator

Collecting an iterator of threads into a vector start the threads


The following snippet shows mapping an iterator into threads and collecting into a Vec

let workers = input
        .chunks(chunk_size)
        .map(|chunk| {
            let lines = chunk.iter().map(|s| s.to_string()).collect::<Vec<_>>();
            thread::spawn(move || count_letters(&lines))
        })
        .collect::<Vec<_>>(); 

Won't this start all threads running (up to the os creating them)? In other words, there is no real limit to how many threads will be created aside from the length of input.

Assuming this is true, if one wanted to do this pattern without instantiating all the threads upon collect, might one use another closure i.e. thread::spawn(move || count_letters(&lines)) -> || thread::spawn(move || count_letters(&lines)) and would this be the rust style?


Solution

  • Won't this start all threads running (up to the os creating them)?

    Yes. Technically the collect is not even necessary here, a for would do.

    Assuming this is true, if one wanted to do this pattern without instantiating all the threads upon collect, might one use another closure

    But then... why bother with the spawn, or the two closures? You can just put that where you'd call the outer closure.

    would this be the rust style?

    The rust style would be to use rayon, probably.

    If you wanted to do that by hand, then the usual: create a queue (an mpmc channel of some sort, possibly bounded), spawn however many workers you have feeding from the queue, push all your work on the queue, then collect the results somehow.