Move Rc to spawn thread?

fn main() {
	let rc = std::rc::Rc::new(3);
		
	let handle = std::thread::spawn(move || {
		println!("rc: {}", rc);
	});

	handle.join();
}

I know Rc not implement Send trait, but I move to new thread. In main thread, we can't access rc anymore, why can't access in spawned thread?

The problem is that multiple Rcs can point to the same value. Suppose that you cloned rc before spawning the thread. Then, both threads could modify the reference count at once, causing data races. If you need a reference-counted value across threads, then Arc might work for your use case.

I know that Rc is not thread-safe. But in previous example, I didn't cloned rc. Why compiler can't find it?

The compiler's analysis (deliberately, this is not a bug) only considers the types of variables, and there's nothing in the type of an Rc<...> value that reflects whether it's been cloned or not.

4 Likes

If you are certain that no other copies of your Rc exist, you can try calling Rc::try_unwrap() to extract the value before sending it to the other thread. It returns Ok(value) only if there are no other references.

2 Likes