Раздел переупорядочения компилятора с взаимным исключением
Поскольку ржавчина применяет мьютекс в качестве контейнера / владельца своих данных и не использует внешнюю защиту, такую как С ++, мне было интересно, может ли компилятор ржавчины переупорядочить внутреннюю часть цикла в следующем псевдокоде (и тем самым , аннулируйте его ..) и если да, то как я могу это предотвратить?
let mut some_type = SomeType::new();
let mut my_lock = MyLock::new();
(0..n).par_iter().for_each(|| {
my_lock.lock();
do_some_stuff_with(&mut some_type);
my_lock.unlock();
})
1 ответ
На самом деле Rust использует ту же модель памяти, что и C++20. Итак, AFAIK вы можете защитить код с помощью блокировки, это просто не лучшая идея (потому что на самом деле ничто не препятствует несинхронизированному доступу к общему ресурсу, и обычно есть тот, который вы хотите защитить в любом случае), а также немного подвержен ошибкам, поскольку вам нужно убедитесь, что вы поддерживаете мьютексгуард живым.
Я действительно не вижу здесь смысла:
let mut my_lock = Mutex::new(SomeType::new());
(0..n).par_iter().for_each(|| {
let mut some_type = my_lock.lock().unwrap();
do_some_stuff_with(&mut some_type);
})
и конечно
par_iter
совершенно бесполезен, так как: вы блокируете весь обратный вызов, поэтому вы просто выполняете линейную итерацию, за исключением непоследовательной и с огромными накладными расходами.