Rust 线程共享数据与send和sync这两个trait息息相关。
- 一个类型实现了send trait,则可以在线程间安全的传递值。
- 一个类型实现了sync trait,则可以在线程间安全的传递不变引用,可以在线程间共享数据。
如果一个类型实现了上述两个trait,则意味着在线程共享数据时能够避免 data races 和 undefined behavior。
Rust的大部分builtin types 都实现了上述两个trait。下图展示了部分数据类型。
下面看一个例子,没有实现上述两个trait的Rc<String> 在线程间共享会怎样?
fn main() {
let s = std::rc::Rc::new("hello".to_owned());
let s2 = s.clone();
std::thread::spawn(move || {
s2.push_str(" world");
});
println!("{}", s);
}
输出的结果:
error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
--> b.rs:4:5
|
4 | std::thread::spawn(move || {
| _____^^^^^^^^^^^^^^^^^^_-
| | |
| | `std::rc::Rc<std::string::String>` cannot be sent between threads safely
5 | | s2.push_str(" world");
6 | | });
| |_____- within this `[closure@b.rs:4:24: 6:6 s2:std::rc::Rc<std::string::String>]`
|
= help: within `[closure@b.rs:4:24: 6:6 s2:std::rc::Rc<std::string::String>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
= note: required because it appears within the type `[closure@b.rs:4:24: 6:6 s2:std::rc::Rc<std::string::String>]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
由上面的错误信息可以看出,std::rc::Rc<std::string::String> 没有实现 std::mark::Send trait,无法在线程间传递值。