I-Code, der ein RefCell
erzeugt und dann auf diese RefCell
einen Verweis übergeben will einen einzigen thread:Wie kann ich garantieren, dass ein Typ, der keine Synchronisation implementiert, tatsächlich sicher zwischen Threads geteilt werden kann?
extern crate crossbeam;
use std::cell::RefCell;
fn main() {
let val = RefCell::new(1);
crossbeam::scope(|scope| {
scope.spawn(|| *val.borrow());
});
}
Im kompletten Code, ich bin mit einem Typ, der ein RefCell
in eingebettet ist es (a typed_arena::Arena
). Ich verwende crossbeam, um sicherzustellen, dass der Thread die Referenz nicht überlebt.
Dies erzeugt den Fehler:
error: the trait bound `std::cell::RefCell<i32>: std::marker::Sync` is not satisfied [E0277]
scope.spawn(|| *val.borrow());
^~~~~
Ich glaube, ich verstehe, warum dieser Fehler passiert: RefCell
nicht gleichzeitig zu aufzuziehen ist von mehreren Threads aufgerufen, und da es verwendet interne Veränderlichkeit, den normalen Mechanismus der ein erfordern Single Mutable Borrow wird nicht mehrere gleichzeitige Aktionen verhindern. Dies wird auch dokumentiert auf Sync
:
Types that are not
Sync
are those that have "interior mutability" in a non-thread-safe way, such asCell
andRefCell
instd::cell
.
Das ist alles schön und gut, aber in diesem Fall, ich weiß, dass nur ein Thread der Lage ist, die RefCell
zuzugreifen. Wie kann ich dem Compiler bestätigen, dass ich verstehe, was ich mache, und ich stelle sicher, dass dies der Fall ist? Natürlich, wenn meine Schlussfolgerung, dass dies tatsächlich sicher ist, falsch ist, würde ich mehr als glücklich sein, warum ich das erfahren würde.
Dies ist zulässig, weil 'RefCell' 'Send' implementiert. –
bluss