Luk*_*odt 6 thread-safety rust
该Arc<T>文件说:
impl<T> Sync for Arc<T> where T: Send + Sync + ?Sized
impl<T> Send for Arc<T> where T: Send + Sync + ?Sized
Run Code Online (Sandbox Code Playgroud)
一个Arc允许多个线程同时访问底层T经由一个不可变的参考&T.只要T不能以非同步方式修改,这是安全的&T.对于具有" 继承可变性 "(几乎所有类型)的所有类型都是如此,对于具有不同步的" 内部可变性 "(例如RefCell,......)的类型则是如此.
据我了解,Send此处不需要绑定.举例来说,我觉得分享我的一个实现人工型Sync,但不是Send在一个Arc很安全.
最后,&T本身也没有这个约束!在对文档Send和Sync我们发现:
impl<'a, T> Send for &'a T where T: Sync + ?Sized
impl<'a, T> Sync for &'a T where T: Sync + ?Sized
Run Code Online (Sandbox Code Playgroud)
而作为Arc<T>允许相同的访问T作为&T呢,我不明白为什么Arc<T>有更多的Send约束.这是为什么?
我相信这是因为它Arc 拥有它包含的值,因此负责删除它.
请考虑以下顺序:
T在线程1中创建它不是Send,这意味着它是不是安全的,这个值移动到另一个线程.Arc句柄中.就像那样,我们将类型的值T从一个线程移动到另一个线程,这违反了内存安全性.
&T不需要Send因为删除&T 永远不允许你删除基础值.
附录:作为一个存在问题的类型的示例,请考虑类似于struct Handle(usize);线程局部资源数组的类型.如果Drop这种类型的实现是错误的线程上运行,这将导致它要么做一个彻头彻尾的越界访问(它试图摧毁并不在此线程存在的资源),或破坏资源那还在使用中.