itertools icon indicating copy to clipboard operation
itertools copied to clipboard

Chunks is not Sync

Open hspug opened this issue 5 years ago • 2 comments

I'd like to use a shared iterator to dispense work items to threads, but it seems I can't.

Is this intentional?

Is there a better way to do this with itertools?

    let chunks = std::sync::Arc::new(std::sync::Mutex::new(itertools::Itertools::chunks(0..100, 10).into_iter()));
    {
        let chunks = chunks.clone();
        std::thread::spawn(move || {
            while let Ok(Some(v)) = chunks.lock().map(|mut x| (*x).next()) {
                for e in v {
                    println!("{:?}", e);
                }
            }
        });
    }

hspug avatar Mar 19 '20 01:03 hspug

So first of I was wondering why the Arc<Mutex> didn't automatically make it Sync. Turns out that references to Cell or RefCell are not Ok. The Compiler can't guarantee that there is no other reference to the same Cell that would allow data to be modified unchecked. The top answer on the following stackoverflow question probably does a better job of explaining it. https://stackoverflow.com/questions/52801244/compiler-says-that-data-cannot-be-shared-between-threads-safely-even-though-the

As for why it isn't made sync, Arcs and Mutexes usually have a runtime-cost for being threadsafe. Also sharing an iterator like that across threads seems to be a bad idea inherently.

How to work around this depends on what you are trying to do. Your workload requires a lot of mutating of the objects use a Channel if you just need reading access crossbeams scoped threads might be for you.

small crossbeam example:

let worker_count = 3;
let data = "Hello, I am an input string with data....";
crossbeam::scope(|s| {
    for i in 0..worker_count {
        s.spawn(move |_| {
            println!("{}", &data[i..].chars().chunks(3).into_iter().step_by(worker_count).flatten().collect::<String>());
        });
    }
}).unwrap();

With that said I think this can be closed?

ghost avatar Feb 23 '21 11:02 ghost

I would add using rayon to the suggestions since it's made pretty much for this usecase

SkiFire13 avatar Feb 24 '21 21:02 SkiFire13