【发布时间】:2016-04-15 14:27:07
【问题描述】:
我的代码创建了一个RefCell,然后想将对该RefCell 的引用传递给一个单个线程:
use crossbeam; // 0.7.3
use std::cell::RefCell;
fn main() {
let val = RefCell::new(1);
crossbeam::scope(|scope| {
scope.spawn(|_| *val.borrow());
})
.unwrap();
}
在完整的代码中,我使用了一个嵌入了RefCell 的类型(typed_arena::Arena)。我使用crossbeam 来确保线程不会超过它所使用的引用。
这会产生错误:
error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
--> src/main.rs:8:15
|
8 | scope.spawn(|_| *val.borrow());
| ^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::RefCell<i32>`
= note: required because it appears within the type `[closure@src/main.rs:8:21: 8:38 val:&std::cell::RefCell<i32>]`
我相信我理解为什么会发生此错误:RefCell 并非旨在从多个线程同时调用,并且由于它使用内部可变性,因此要求单个可变借用的正常机制不会阻止多个并发操作。这甚至记录在Sync:
不是
Sync的类型是那些以非线程安全形式具有“内部可变性”的类型,例如cell::Cell和cell::RefCell。
这一切都很好,但是在这种情况下,我知道只有一个线程能够访问RefCell。我如何向编译器确认我理解我在做什么并确保是这种情况?当然,如果我认为这实际上是安全的推理不正确,我很乐意被告知原因。
【问题讨论】:
标签: thread-safety rust unsafe