impl<T> Sync for Arc<T> where T: Send + Sync + ?Sized
impl<T> Send for Arc<T> where T: Send + Sync + ?Sized
Arc
允许多个线程通过不可变引用T
同时访问基础&T
。只要T
无法通过&T
以不同步的方式修改,这就是安全的。对于具有“继承的可变性”(几乎所有类型)的所有类型都是如此,对于具有未同步的“内部可变性”(例如RefCell
, ..)。
据我了解,此处不需要Send
界限。例如,我认为在Arc
中共享my artificial type which implements Sync
but not Send
是安全的。
最后,&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
由于Arc<T>
允许T
与&T
的访问次数相同,我不明白为什么Arc<T>
有Send
的额外限制。 为什么?
答案 0 :(得分:8)
我相信这是因为Arc
拥有它包含的值,因此负责删除它。
考虑以下顺序:
T
类型的值。它不是Send
,这意味着将此值移动到另一个线程 是安全的。Arc
句柄。就这样,我们已将T
类型的值从一个线程移动到另一个线程,这违反了内存安全。
&T
并不需要Send
,因为删除&T
永远可以删除基础值。
附录:作为一个存在问题的类型示例,请考虑类似struct Handle(usize);
的类型,该类型由线程局部资源数组支持。如果这种类型的Drop
实现在错误的线程上运行,这将导致它 执行越界访问(它试图销毁不具有&的资源) #39; t存在于此线程上),或者破坏仍在使用的资源。