#1172·rayon

Add synchronization guarantees for `ParallelIterator::for_each*`

Author: andrewsoninCreated May 30, 2024Updated Jul 10, 2026

Consider the following code:

rust
use std::sync::atomic::{AtomicUsize, Ordering};

use rayon::iter::{IntoParallelIterator, ParallelIterator};

fn main() {
    let mut counter = AtomicUsize::new(0);

    (0..10).into_par_iter()
        .for_each(
            |_| {
                counter.fetch_add(1, Ordering::Relaxed);
            }
        );
    // Can these operations fail?
    assert_eq!(counter.load(Ordering::Relaxed), 10);
    assert_eq!(*counter.get_mut(), 10);
}

The C++20 memory model itself does not guarantee that these assertions will not fail.

Although the rayon implementation does guarantees this (upon .for_each completion the mutex is unlocked, which is always a release-store), the ParallelIterator documentation does not reflect this.