multithreading - 如何从线程返回包含 Rc 的类型?

标签 multithreading rust reference-counting

我正在生成一个线程,它构建的本质上是一棵树,稍后需要它,因此可以在线程外计算。举个例子,想想Foo { inner: HashMap<Bar, Rc<FooBar>> }。线程的关闭不会从周围环境捕获任何东西。

问题是Rc使整个类型成为!Send。这阻止了Foo返回到生成线程。实际上,Rc“毒害”了Foo

我不明白为什么由派生线程创建并返回的类型仍然需要是Send的原因:它强制所有内部类型(在这种情况下,Rc中的HashMap,在Foo ,变为 Send 。从衍生线程的角度来看,这是无法修复的。 它强制生成的线程始终使用原子计数,而实际上两个线程同时访问引用计数器的可能性为零。

有没有办法从线程返回(不是共享!)包含Rc的类型?我是否遗漏了对Send的理解?

最佳答案

[T]here is actually zero possibility for both threads to access the refcounter simultaneously.

但是编译器无法理解,所以您必须说“不,真的,相信我,我知道它看起来很狡猾,但实际上是安全的。”这就是 unsafe 的用途。

应该很简单

unsafe impl Send for Foo {}

来自Nomicon :

  • Rc isn't Send or Sync (because the refcount is shared and unsynchronized).

Rc 本身 Send 是不安全的,因为 Rc 暴露了一个接口(interface),如果在线程之间发送是不安全的。但是 Foo,正如您所描述的那样,公开了一个接口(interface),该接口(interface)不是在线程之间发送是不安全的,所以只需 unsafe impl 它并继续你的方式。

假设,也就是说,接口(interface)可以安全地在线程之间发送。例如,Foo 不能有克隆并返回内部 Rc 的方法(因为您可以使用它有效地“走私”一个裸露的 Rc 通过 Foo 进入另一个线程。

如果 Foo 并非始终 安全发送,但您碰巧知道某些特定 Foo 是安全发送,更好的方法是暂时将其包装在 Send 类型中,如 Shepmaster's answer建议。

关于multithreading - 如何从线程返回包含 Rc 的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54446633/

相关文章:

ios - Swift - Grand Central Dispatch 与 block /闭包

rust - 是否可以检查字段是否实现了具有自定义派生的特征?

rust - 无法在装箱特征对象上调用方法,因为它的生命周期不够长

python - 了解 python 引用计数以调试 c 扩展

garbage-collection - 为什么垃圾收集器在分配之前要等待?

java - Android 中任何线程中的异常为何以及如何导致整个应用程序崩溃

c# - 在哪里可以学习使用 C# 构建桌面应用程序?

file - 如何过滤文件路径然后使用结果路径

delphi - 在两个地方引用接口(interface)对象

java - java中线程通信的锁与条件