Rust中的Send和Sync不仅是对初学者,就是持续学习者,都是一个认知上的挑战。

一、Rust世界中的Send和Sync

关于Send和Sync,有权威的引用,如下:

T: Send means T and &mut T (which allow dropping T) can be passed between threads.
T: Sync means &T (which allows shared/aliased access to T) can be passed between threads. Either or both may be true for any given type.

T: Sync ≡ &T: Send (by definition).

这个翻译一下就是:

T: Send表示T和&mut(允许丢弃T)可以在线程之间传递。[传递所有权]
T: Sync意味着&T(允许共享/别名访问T)可以在线程之间传递。[传递引用]
对于任何给定类型,其中一个或两个都可能为真。
T: Sync与&T: Send完全等价(根据定义)。

1、Send + Sync:常见的数据类型。

i8, f32, bool, char, &str, String等

2、 Send + !Sync:常见可以内部可变性的

包括:Cell 、RefCell。

unsafe impl<T: ?Sized> Send for RefCell<T> where T: Send {}
impl<T: ?Sized> !Sync for RefCell<T> {}

3、!Send + Sync:常见需要特定线程释放

包括:MutexGuard,RwLockWriteGuard、RwLockReadGuard.

impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}

4、!Send + !Sync: 常见野指针类

常见的有:Rc, *const T, *mut T,NonNull等。

impl<T: PointeeSized> !Send for NonNull<T> {}
impl<T: PointeeSized> !Sync for NonNull<T> {}

5、特别的类型

比如:

unsafe impl<T: ?Sized> Sync for Exclusive<T> {}
impl<T: ?Sized> !Sync for UnsafeCell<T> {}

6、需要与特定泛型T约束有关的类型

比如:

// 有约束条件
unsafe impl<T: ?Sized + Sync + Send> Send for Arc<T> {}
unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
 // 有约束条件
unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
// 有约束条件
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}

二、现实世界的中Send和Sync

以书(文字作品)为例,试图来与Rust的Send和Sync进行映射:

1、 Send +Sync: 流通性和交易性

你在网络上写的小说,显然,你对书籍有版权,是所有者。通过网络,大家都看到你的作品,你也对小说明码标价,转让书拍版权拍成电影。

此时可以Send(转让所有权,拍电影,改编,进行再次创作,&mut);给大家传阅,这个时侯就是Sync(大家都可以看,可以转发,但不能拍电影及改编再创作)。

2、!Send +!Sync:隐私性或无法保证

比如你写的日记,你并不准备给其它人看。复印本也不能给其它人看。受保护的国家机密或产品秘方。
或者说图书馆的书,本身不能卖出(所有权只能是图书馆),书只能实物借阅,显然,每一本书只能同时借给一个人看,而不是多个人看。

3、Send +!Sync:对变化的控制无法保证

举例:比如二手市场的实体书,可以出售,但同一时间,只允许一个人翻阅,无法多人翻阅。这个时侯,就只是Send,但不是Sync。
或者说,你的书可以转让,但是不能借阅,因为你无法保证,别人在借阅时会乱涂乱画,或损坏书的完整性。

4、!Send + Sync: 必要的控制力

比如,对一些古籍文物字画(如苏轼的书法真迹),显然不能进行买卖,所有权在国家。大家只能在博物馆展出时进行参观。什么时侯举行展出或开馆,显然是由国家来定的(由于安保、场馆等原因),不能由参观者来定开放时间。

每一个概念,不是无中生有,在现实世界中一定是映射。Send和Sync也是一样。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐