У меня есть код, который создает RefCell
, а затем хочет передать ссылку на этот RefCell
к одного нити:Как я могу гарантировать, что тип, который не реализует Sync, может быть безопасно распределен между потоками?
extern crate crossbeam;
use std::cell::RefCell;
fn main() {
let val = RefCell::new(1);
crossbeam::scope(|scope| {
scope.spawn(|| *val.borrow());
});
}
В полный код, я использую тип, который имеет встроенный в RefCell
это (typed_arena::Arena
). Я использую crossbeam, чтобы убедиться, что поток не переживает требуемую ссылку.
Это дает ошибку:
error: the trait bound `std::cell::RefCell<i32>: std::marker::Sync` is not satisfied [E0277]
scope.spawn(|| *val.borrow());
^~~~~
Я считаю, я понимаю, почему это происходит ошибка: RefCell
не предназначен называться одновременно из нескольких потоков, и, поскольку она использует внутреннюю переменчивость, нормальный механизм требуя единственный измененный заимствование не предотвратит множественные одновременные действия. Это даже задокументировано на Sync
:
Types that are not
Sync
are those that have "interior mutability" in a non-thread-safe way, such asCell
andRefCell
instd::cell
.
Это все хорошо, но в этом случае, я знаю, что только один поток может получить доступ к RefCell
. Как я могу подтвердить компилятору, что я понимаю, что делаю, и я гарантирую, что это так? Конечно, если мои рассуждения о том, что это на самом деле безопасно, неверны, я был бы более чем счастлив, если вам скажут почему.
Это разрешено, потому что 'RefCell' реализует 'Отправить'. –
bluss