【发布时间】:2018-06-23 15:04:09
【问题描述】:
我有下面的代码。使用注释掉的部分,它正在工作。当我取消注释部分时,它不再编译。
如何调整注释部分以使其工作,即我想让线程同时访问表达式树。
当我尝试它时,编译器以关于线程安全性的错误开始。
我阅读了 Rust 书籍并且了解 C/C++,但还没有完全理解 Rust 类型系统和语义。
use std::thread;
use std::sync::Arc;
pub trait Expr {
fn run(&self) -> i32;
}
pub struct ConstantExpr {
n: i32,
}
impl ConstantExpr {
pub fn new(n: i32) -> Self {
Self { n }
}
}
impl Expr for ConstantExpr {
fn run(&self) -> i32 {
self.n
}
}
pub struct AddExpr {
expr1: Box<Expr>,
expr2: Box<Expr>,
}
impl AddExpr {
pub fn new(expr1: Box<Expr>, expr2: Box<Expr>) -> Self {
Self { expr1, expr2 }
}
}
impl Expr for AddExpr {
fn run(&self) -> i32 {
self.expr1.run() + self.expr2.run()
}
}
struct Container {
x: i32,
cached_expr: Arc<Expr>,
}
impl Container {
fn new() -> Self {
Self {
x: 0,
cached_expr: Arc::new(AddExpr::new(
Box::new(ConstantExpr::new(10)),
Box::new(ConstantExpr::new(1)),
)),
}
}
}
fn main() {
let container = Arc::new(Container::new());
let container1 = Arc::clone(&container);
/*
let thread1 = thread::spawn(move || {
println!("thread1: {}", container1.x);
println!("thread1: {}", container1.cached_expr.run());
});
*/
println!("main: {}", container.x);
println!("main: {}", container.cached_expr.run());
//thread1.join().unwrap();
}
错误:
error[E0277]: the trait bound `Expr + 'static: std::marker::Send` is not satisfied
--> src/main.rs:64:19
|
64 | let thread1 = thread::spawn(move || {
| ^^^^^^^^^^^^^ `Expr + 'static` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `Expr + 'static`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Expr + 'static>`
= note: required because it appears within the type `Container`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Container>`
= note: required because it appears within the type `[closure@src/main.rs:64:33: 67:6 container1:std::sync::Arc<Container>]`
= note: required by `std::thread::spawn`
error[E0277]: the trait bound `Expr + 'static: std::marker::Sync` is not satisfied
--> src/main.rs:64:19
|
64 | let thread1 = thread::spawn(move || {
| ^^^^^^^^^^^^^ `Expr + 'static` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `Expr + 'static`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Expr + 'static>`
= note: required because it appears within the type `Container`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Container>`
= note: required because it appears within the type `[closure@src/main.rs:64:33: 67:6 container1:std::sync::Arc<Container>]`
= note: required by `std::thread::spawn`
【问题讨论】:
标签: rust thread-safety lifetime