Rust的异步并发编程中,大量的接口参数、返回值要求类型为Send、Sync,那这2个trait到底是什么意思,有什么区别,为什么在异步编程中需要他们,以及类型是如何实现这些trait的;本文会从上面几个问题入手带你深入了解这2个trait.
Sync
:1)行为上:允许一个对象在多个线程中被同时使用;2)原理上:将一个实现了Sync类型的不可变引用安全的传递给另一个线程,即只有实现了Sync Trait的类型才可以安全地被多个线程引用。
Send
: 1) 行为上:允许一个对象在多个线程中在不同时间被使用, 2) 原理上:允许对象在线程间转移所有权,只有实现了Send trait的类型才可以在线程间转移所有权
从上面的解释可以看到,2者重要的区别是:行为上:多线程中同一个对象的使用方式,Sync属性的对象可以在多线程中被同时使用,而Send属性的对象同一时间只能有一个线程使用。原理上:一个是按值传递涉及所有权的转移,另一个是按引用传递.
Rust中大多数类型既实现了Send也实现了Sync,甚至不必为自定义的结构体/枚举手动实现这些trait,Rust会自动帮你实现;如果结构体或枚举的所有字段都是Send那它也是Send,同理Sync。
但Rust中有些类型刻意设计为Send但非Sync的,如:mpsc::Receiver类型,保证了mpsc通道的接收端一次只能被一个线程使用。
少数既不是Send也 不是Sync的类型大多数使用了非线程安全的内部可变性,如引用计数器指针:std::rc::Rc<T>
;
Rc<String>
是Sync的,那么在线程间通过共享引用共享单个Rc时就会出发数据竞争,如:2个线程同时增加共享引用计数会导致引用技术结果变得不准确。在异步编程中对于跨线程边界使用的函数,Send、Sync会作为函数类型签名中的约束。当spawn一个线程时传入的闭包必须实现了Send trait,意味着它包含的所有值都必须是Send;同样如果通过通道将值发送到另一个线程,该值也必须是Send.
https://stackoverflow.com/questions/59428096/understanding-the-send-trait
Rust 程序设计(第2版)
Rust 权威指南
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。