Sync也是一个标记型trait,它标记了实现它的类型可以安全的在线程间共享访问。 所谓共享,其实就是可以安全的引用。而如果&T实现了Send(可安全移动),那么T就实现了Sync(可安全共享其的引用)。 也就是说,需要并发中需要安全引用(&T)都需要T被标记实现了Sync,否则编译器会报错。 又是一个巧妙的设计,通过trait boun...
对于任意类型 T,如果 &T是 Send ,T 就是 Sync 的 之前出错的代码修改为如下形式,增加 Sync 标记,编译通过。 代码语言:javascript 复制 fn test2<T:Send+Sync+'static>(mut aa:AA<T>){letha=async_std::task::spawn(asyncmove{aa.run().await;});} ...
fn test1<T: Send + Sync + 'static>(t: T) { let b = Arc::new(t); let bb = b.clone(); thread::spawn( move|| { let cc = &bb; }); } 根据上面的分析,不难推导出条件 T: Send + Sync + 'static 的来龙去脉:Closure: Send + 'static ⇒ Arc: Send + ’static ⇒ T: Se...
Send trait是一个标记型(marker)的trait, 它没有实际方法,也不需要用户主动去实现,一般基本类型都实现了Send。而复合类型如果包含的所有成员都实现了Send,那么它也自动实现了Send。(后面的Sync也是这样的自动trait) 也就是说,需要并发中需要安全传递值都需要被标记实现Send,否则编译器会报错。 并发安全检查变成了trai...
根据上面的分析,不难推导出条件 T: Send + Sync + 'static 的来龙去脉:Closure: Send + 'static ⇒ Arc<T>: Send + ’static ⇒ T: Send + Sync + 'static。 然而,在异步协程代码中有一种常见情况,推导过程则显得比较隐蔽,值得说道说道。考察以下代码: ...
Sync:实现Sync的类型可以安全的在线程间传递不可变借用。 现在我们可以看一下spawn函数的源码 #[stable(feature ="rust1", since ="1.0.0")]pubfnspawn<F, T>(f: F)->JoinHandle<T>whereF:FnOnce()->T, F:Send+'static, T:Send+'static{ ...
Sync:实现Sync的类型可以安全的在线程间传递不可变借用。 现在我们可以看一下spawn函数的源码 代码语言:txt 复制 #[stable(feature = "rust1", since = "1.0.0")] pub fn spawn<F, T>(f: F) -> JoinHandle<T> where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static ...
# use std::sync::Arc; # use std::sync::Mutex; # use std::thread; # # pub struct ThreadPool { # workers: Vec<Worker>, # sender: mpsc::Sender<Job>, # } # # type Job = Box<dyn FnOnce() + Send + 'static>; # enum Message { ...
617 | F: Send + 'static, | --- required bythisbound in `spawn`| = help: within `[closure@src/main.rs:65:36: 68:10]`, the trait `Send` is not implementedfor`Rc<Mutex<i32>>`= note: required because it appears within the type `[closure@src/main.rs:65:36: 68:10]` 错误...
Rust 有一些特殊的标记 trait , 如Send和Sync。简单来说,如果一个类型实现了Send,则意味着该类型的值可以从一个线程传递到另一个线程。如果一个类型实现了Sync,则意味着可以在多线程间使用共享引用共享其值。 Rc指针没有实现Send和Sync,假设两个线程拥有指向相同数据的Rc指针,在某个时间点,两个线程同时clone并生...