Rust 跨线程将trait对象作为属性共享结构
我有下面的代码。有了注释掉的部分,它就开始工作了。当我取消注释部分时,它不再编译 我如何调整注释部分以使其工作,也就是说,我想让线程同时访问表达式树 当我尝试它时,编译器会以关于线程安全性的错误开始 我读过Rust的书,了解C/C++,但还不完全了解Rust类型系统和语义Rust 跨线程将trait对象作为属性共享结构,rust,thread-safety,lifetime,Rust,Thread Safety,Lifetime,我有下面的代码。有了注释掉的部分,它就开始工作了。当我取消注释部分时,它不再编译 我如何调整注释部分以使其工作,也就是说,我想让线程同时访问表达式树 当我尝试它时,编译器会以关于线程安全性的错误开始 我读过Rust的书,了解C/C++,但还不完全了解Rust类型系统和语义 use std::thread; use std::sync::Arc; pub trait Expr { fn run(&self) -> i32; } pub struct ConstantExp
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();
}
使用std::thread;
使用std::sync::Arc;
pub特征表达式{
fn运行(&self)->i32;
}
康斯坦特克斯酒店{
n:i32,
}
康斯坦特斯普雷姆酒店{
新发布(n:i32)->Self{
自{n}
}
}
ConstantExpr的impl Expr{
fn运行(&self)->i32{
赛尔夫
}
}
pub结构加法器{
expr1:Box,
expr2:Box,
}
impl加法器{
pub fn new(expr1:Box,expr2:Box)->Self{
自我{expr1,expr2}
}
}
加法器的impl Expr{
fn运行(&self)->i32{
self.expr1.run()+self.expr2.run()
}
}
结构容器{
x:i32,
缓存的_expr:Arc,
}
impl容器{
fn new()->Self{
自我{
x:0,,
缓存的_expr:Arc::new(AddExpr::new(
盒子::新的(康斯坦特斯普::新的(10)),
盒子::新的(康斯坦特斯普::新的(1)),
)),
}
}
}
fn main(){
让container=Arc::new(container::new());
让container1=Arc::clone(&container);
/*
让thread1=thread::spawn(移动| |){
println!(“thread1:{}”,container1.x);
println!(“thread1:{}”,container1.cached_expr.run());
});
*/
println!(“main:{}”,container.x);
println!((“main:{}”,container.cached_expr.run());
//线程1.连接().展开();
}
错误:
error[E0277]:特性绑定'Expr+'static:std::marker::Send'不满足
-->src/main.rs:64:19
|
64 | let thread1=线程::繁殖(移动| |{
|^^^^^^^^^^^^^^^`Expr+'static`无法在线程之间安全发送
|
=help:trait`std::marker::Send`未为`Expr+'静态实现`
=注:由于'std::marker::Send'的impl中对'std::sync::Arc src/main.rs:64:19的要求,因此需要输入'std::marker::Send'
|
64 | let thread1=线程::繁殖(移动| |{
|^^^^^^^^^^^^^^ ^`Expr+'static`无法在线程之间安全共享
|
=帮助:特性'std::marker::Sync'未为'Expr+'静态实现`
=注意:由于'std::marker::Send'的impl中对'std::sync::Arc'的要求,因此需要此选项我发现错误消息非常简单:
- trait
std::marker::Send
没有为Expr+'static
- 由于
std::sync::Arc
的std::marker::Send
的impl上的要求而需要,无法保证跨线程安全发送(Send
)或共享(sync
)
将Send
和Sync
作为超级特征添加到Expr:
pub trait Expr: Send + Sync { /* ... */ }
或者将它们作为特征边界添加到特征对象:
pub struct AddExpr {
expr1: Box<Expr + Send + Sync>,
expr2: Box<Expr + Send + Sync>,
}
impl AddExpr {
pub fn new(expr1: Box<Expr + Send + Sync>, expr2: Box<Expr + Send + Sync>) -> Self {
Self { expr1, expr2 }
}
}
struct Container {
x: i32,
cached_expr: Arc<Expr + Send + Sync>,
}
pub-struct-AddExpr{
expr1:Box,
expr2:Box,
}
impl加法器{
pub fn new(expr1:Box,expr2:Box)->Self{
自我{expr1,expr2}
}
}
结构容器{
x:i32,
缓存的_expr:Arc,
}
另见:
我发现错误消息非常简单:
- trait
std::marker::Send
没有为Expr+'static
- 由于
std::sync::Arc
的std::marker::Send
的impl上的要求而需要,无法保证跨线程安全发送(Send
)或共享(sync
)
将Send
和Sync
作为超级特征添加到Expr:
pub trait Expr: Send + Sync { /* ... */ }
或者将它们作为特征边界添加到特征对象:
pub struct AddExpr {
expr1: Box<Expr + Send + Sync>,
expr2: Box<Expr + Send + Sync>,
}
impl AddExpr {
pub fn new(expr1: Box<Expr + Send + Sync>, expr2: Box<Expr + Send + Sync>) -> Self {
Self { expr1, expr2 }
}
}
struct Container {
x: i32,
cached_expr: Arc<Expr + Send + Sync>,
}
pub-struct-AddExpr{
expr1:Box,
expr2:Box,
}
impl加法器{
pub fn new(expr1:Box,expr2:Box)->Self{
自我{expr1,expr2}
}
}
结构容器{
x:i32,
缓存的_expr:Arc,
}
另见: