如何理解 Sync、Send?
Sync
和 Send
是 rust 安全并发中两个至关重要的 marker
,但绝大多数的文档或书籍每当谈到它们就只是直接抛出它们的语义:
实现了
Send
的类型,可以安全地在线程间传递所有权。也就是说, 可以跨线程移动。实现了
Sync
的类型, 可以安全地在线程间传递不可变借用。也就是说,可以跨线程共享。
这两句话的确很重要(没看过的读者可以多看几遍再继续阅读下文)。但如果只把这个拿出来,像我这样不熟练的 rust 用户可能会觉得似懂非懂,很多概念混杂在一起 —— rust 中关于可变不可变的讨论太多了。
导火索 RwLock
我之所以决定彻底搞清楚这两个东西是因为我使用标准库中的 RwLock
遇到了一些问题,查看源码之后发现这两行(先不管 Send
):
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
稍懂 rust 的同学应该就可以看懂,这代码的意思是,只有当类型 T
实现了 Sync
,RwLock<T>
才会实现 Sync
。
欸!?我就纳闷了,读写锁读写锁,怎么说也是个锁。锁不就是把不 Sync
的类型变 Sync
的存在吗?
我马上又去看了一下 Mutex
,果然不出我所料: