Appearance
基于 Send 和 Sync 的线程安全
一、Rc 和 Arc 源码对比
rust
// Rc源码片段
impl<T: ?Sized> !marker::Send for Rc<T> {} // 此处Send被移除了
impl<T: ?Sized> !marker::Sync for Rc<T> {} // 此处Sync被移除了
// Arc源码片段
unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
// Rc源码片段
impl<T: ?Sized> !marker::Send for Rc<T> {} // 此处Send被移除了
impl<T: ?Sized> !marker::Sync for Rc<T> {} // 此处Sync被移除了
// Arc源码片段
unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
!代表移除特征的相应实现,上面代码中Rc<T>
的Send和Sync特征被特地移除了实现,而Arc<T>
则相反,实现了Sync + Send
,再结合之前的编译器报错,大概可以明白了:Send和Sync是在线程间安全使用一个值的关键。
二、Send 和 Sync
Send
和Sync
是 Rust 安全并发的重中之重,但是实际上它们只是标记特征(marker trait,该特征未定义任何行为,因此非常适合用于标记), 来看看它们的作用:
- 实现
Send
的类型可以在线程间安全的传递其所有权 - 实现
Sync
的类型可以在线程间安全的共享(通过引用)