5 分钟速读之 Rust 权威指南(三十三)Send&Sync
Send trait 和 Sync trait
前面几节过后,并发的基本使用就聊完了,最后还剩下一点,前面我们在创建线程后,允许将数据的所有权转移到线程中(比如:i32,String,Vec<T>, Arc<T>等),但是并非所有数据都可以转移,比如当我们前面尝试将 Rc<T>所有权转移到线程中时就会报错:
实际上在于 Rc<T>没有 Send trait,而 rust 大部分类型都实现了这个 trait。
Send trait 允许线程间转移所有权
只有实现了 Send trait 的类型才可以安全地在线程间转移所有权,除了 Rc<T>等极少数的类型,几乎所有的 Rust 类型都实现了 Send trait。
如果我们将克隆后的 Rc<T>值的所有权转移到了另外一个线程中,那么两个线程就有可能同时更新引用计数值并进而导致计数错误。
Sync trait 允许多线程同时访问
只在线程中传递是不够的的,还需要我们在线程中能够对数据进行访问,比如前面用过的 Mutex<T>就可以在线程中访问,而 RefCell<T>就不可以:
只有实现了 Sync trait 的类型才可以安全地被多个线程引用,类型 Mutex<T>是 Sync 的,可以被多个线程共享访问,类型 RefCell<T>不满足 Sync 约束,实现的运行时借用检查并没有提供有关线程安全的保证。
手动实现 Send 和 Sync 是不安全的
当某个类型完全由实现了 Send 与 Sync 的类型组成时,它就会自动实现 Send 与 Sync。
我们并不需要手动地为此种类型实现相关 trait。这两个被称作”标签 trait“,Send 与 Sync 其实并没有任何可供实现的方法。它们仅仅被用来标识并发相关的不可变性。
版权声明: 本文为 InfoQ 作者【码生笔谈】的原创文章。
原文链接:【http://xie.infoq.cn/article/3fa93ccb7e7a2ceb6bc5638b7】。文章转载请联系作者。
评论