Hi folks,
One thing I don't quite understand is why Send
is required when sharing trait object between threads. For example,
use std::sync::{Arc, Mutex};
use std::thread;
trait Foo {
fn inc(&mut self, i32) -> i32;
}
struct FooImpl {
c: i32,
}
impl Foo for FooImpl {
fn inc(&mut self, c: i32) -> i32 {
self.c += c;
self.c
}
}
fn main() {
let counter: Arc<Mutex<Box<Foo>>> = Arc::new(Mutex::new(Box::new(FooImpl { c: 0 })));
let mut threads = Vec::new();
for _ in 0..10 {
let counter = counter.clone();
threads.push(thread::spawn(move || {
let mut w = counter.lock().unwrap();
let c = (*w).inc(1);
println!("counter={}", c);
}));
}
for thread in threads {
thread.join().unwrap();
}
}
In the above code, each thread holds a mutex protected copy of the trait object. At any given time, at most one of them will access the object. Because trait object is implemented as fat pointers, and all the threads share the same address space, why can't Rust just send the fat pointer among spawned threads? In other words, why don't Rust make all the trait objects implement Send
by default?