Ho codice che crea un RefCell
e poi vuole passare un riferimento a tale RefCell
ad una discussione singolo:Come posso garantire che un tipo che non implementa Sync possa effettivamente essere condiviso in modo sicuro tra i thread?
extern crate crossbeam;
use std::cell::RefCell;
fn main() {
let val = RefCell::new(1);
crossbeam::scope(|scope| {
scope.spawn(|| *val.borrow());
});
}
Nel codice completo, sto usando un tipo che ha un RefCell
incorporato in it (a typed_arena::Arena
). Sto usando crossbeam per assicurarmi che il thread non sopravviva al riferimento che ci vuole.
Questo produce l'errore:
error: the trait bound `std::cell::RefCell<i32>: std::marker::Sync` is not satisfied [E0277]
scope.spawn(|| *val.borrow());
^~~~~
Credo di capire perché questo errore accade: RefCell
non è progettato per essere chiamato contemporaneamente da più thread, e poiché usa mutabilità interno, il normale meccanismo di richiedere un il singolo prestito mutabile non impedirà più azioni simultanee. Questo è anche documentata sul Sync
:
Types that are not
Sync
are those that have "interior mutability" in a non-thread-safe way, such asCell
andRefCell
instd::cell
.
Questo è cosa buona e giusta, ma in questo caso , so che solo un thread è in grado di accedere al RefCell
. Come posso affermare al compilatore che capisco quello che sto facendo e mi assicuro che sia così? Certo, se il mio ragionamento sul fatto che questo è effettivamente sicuro non è corretto, sarei più che felice di sentirmi dire perché.
Ciò è consentito perché 'RefCell' implementa 'Invia'. –
bluss