Sync 和 Send trait的可扩展并发
Sync 和 Send 是内嵌在Rust语言中的 std::marker.
Send trait 允许数据在线程间转移所有权.
几乎所有的Rust类型都是Send的, 不过有一些例外, 比如 Rc<T> , 如果多个线程可能同时更新Rc的引用计数, 从而导致计数错误.
Rust展开
12345678910111213141516171819202122232425262728293031323334353637383940
use std::rc::Rc;
use std::thread;
use std::sync::{Mutex};
fn main(){
let x = Rc::new (Mutex::new(0) );
let mut thes = vec![];
for _ in 0..6 {
let x = Rc::clone(&x);
let th = thread::spawn(move ||{
let mut y = x.lock().unwrap();
*y = *y + 1;
});
thes.push(th);
}
for th in thes {
th.join().unwrap();
}
println!("{}", x.lock().unwrap());
}
/**********************output*************************/
error[E0277]: `Rc<Mutex<i32>>` cannot be sent between threads safely
--> src/main.rs:11:14
|
11 | let th = thread::spawn(move ||{
| ______________^^^^^^^^^^^^^_-
| | |
| | `Rc<Mutex<i32>>` cannot be sent between threads safely
12 | | let mut y = x.lock().unwrap();
13 | | *y = *y + 1;
14 | | });
| |_____- within this `[closure@src/main.rs:11:28: 14:6]`
|
= help: within `[closure@src/main.rs:11:28: 14:6]`, the trait `Send` is not implemented for `Rc<Mutex<i32>>`
= note: required because it appears within the type `[closure@src/main.rs:11:28: 14:6]`
note: required by a bound in `spawn`
通过Send Rust 可以保证不会意外的将未实现Sendtrait 的数据在线程间转移.
任何完全由Send标记的的类型组成的数据,也会被标记为Send. 除了 裸指针(raw pointer)外, 所有的基本类型都是可Send的
Sync允许多线程间的安全访问, 实现了Sync的类型可以在多个线程中拥有其值的引用.
对任意类型T ,如果 &T 实现了Send , 则T是Sync 的, 也即意味着他的引用可以安全的发送到多个线程中.
和Send类似, 基本类型是Sync的,完全有实现了Sync的类型组成的类型也是 Sync的.
RefCell 和 Cell 都不是Sync的, 因为运行时的借用检查不是线程安全的.
通常并不需要手动实现Send 和 Sync , 他们是标记trait, 甚至都没有需要实现的方法. 他们只是用来标注并发相关的检查
Rust展开
1234567891011121314151617181920
#[derive(Send, Sync)]
struct A{}
/***************output**************/
error: cannot find derive macro `Send` in this scope
--> src/lib.rs:1:10
|
1 | #[derive(Send)]
| ^^^^
|
note: unsafe traits like `Send` should be implemented explicitly
error: cannot find derive macro `Sync` in this scope
--> src/lib.rs:1:16
|
1 | #[derive(Send, Sync)]
| ^^^^
|
note: unsafe traits like `Sync` should be implemented explicitly