【问题标题】:Why does Arc<Mutex<T>> require T: Sync + Send?为什么 Arc<Mutex<T>> 需要 T: Sync + Send?
【发布时间】:2024-04-18 01:35:02
【问题描述】:

如果我有一个在线程之间发送不安全的类型,我用Arc&lt;Mutex&lt;T&gt;&gt; 包装它。这样我可以保证当我访问它时,我需要先解锁它。但是,当 T 没有实现 Send + Sync 时,Rust 仍然会抱怨。

它不应该适用于任何类型吗?在我的例子中,T 是一个通过 FFI 访问 C 对象的结构,所以我不能将它标记为 Sync + Send

在这种情况下我能做什么?为什么 Rust 不接受 Arc&lt;Mutex&lt;T&gt;&gt; 在线程之间安全共享?

【问题讨论】:

    标签: rust


    【解决方案1】:

    仅仅因为你是唯一一个(一次)访问某些东西的人,并不意味着它突然变得可以从不同的线程访问东西。它只是防止一个问题:数据竞争。但是跨线程移动对象可能还有其他问题。

    例如,通常只能从主线程调用低级窗口 API。许多低级 API 也只能从它们被初始化的线程调用。如果你将这些 API 包装在 Rust 对象中,你不希望这些对象在线程间移动无论如何

    【讨论】:

    • 有没有办法告诉 Rust Arc&lt;Mutex&lt;MyType&gt;&gt; 可以安全地在线程之间共享,而不会使类型本身 MyType saf 在线程之间共享?
    • 就我而言,我只需要防止数据竞争
    • @GuerlandoOCs 将其包装在一个类型中并为该类型手动实现Send。当然这是你向编译器保证Send是安全的,如果你错了,你就失去了安全性。
    • @GuerlandoOCs 其实你应该可以直接写impl Send for Arc&lt;Mutex&lt;MyType&gt;&gt; {}
    • @GuerlandoOCs 在原文中您说您不能将结构标记为发送,但是……这不是真的吗?只要类型在您的控制之下,您就可以将其标记为Send。这仅仅意味着该结构不是线程绑定的(有些是线程绑定的)。只要T: SendMutex&lt;T&gt; 就是Sync