Add synchronization guarantees for `ParallelIterator::for_each*`
Author: andrewsoninCreated May 30, 2024Updated Jul 10, 2026
Consider the following code:
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.
Source: rayon-rs/rayon