gpt4 book ai didi

multithreading - 这个稍作修改的 Rc<()> 是 Sync,而不是 Send,对吧?

转载 作者:行者123 更新时间:2023-11-29 07:48:32 25 4
gpt4 key购买 nike

我搜索了 Sync 的类型, 但不是 Send ,因为它通常看起来像一个特征是另一个特征的超集(“实现 Sync 的每个类型也实现了 Send”)。我找到了 this question ,但唯一真正的答案真的很复杂。

所以我想出了这段代码:

struct Foo(Rc<()>);  // <-- private field

impl Foo {
fn my_clone(&mut self) -> Self { // <-- mutable borrow
Foo(self.0.clone())
}
}

我知道编译器不会自动执行Send也不Sync适合我的类型;但我感兴趣的是我可以手动安全地实现什么。我认为:

  • 应该可以实现Sync :具有对 Foo不可变 引用不会让我们对它做任何事情(因为我们只能通过可变/独占引用调用 my_clone())。什么都不做,就不会出错,对吧?

  • 它应该能够实现Send :我们可以克隆我们的 Foo在主线程中(在启动另一个线程之前)获取第二个对象。现在两个对象共享一些内存(引用计数,存储在 Cell<usize> 中)。如果我现在可以将这些对象之一发送到另一个线程,则两个线程都将拥有 Foo 的所有权。 ,引用相同的内存。因此两个对象都可以调用 my_clone()同时,导致对引用计数的同步、不同步、可变访问(数据竞争)。

这个推理是正确的还是我遗漏了什么?

最佳答案

I know that the compiler won't automatically implement Send nor Sync for my type.

确实,编译器自动实现了SendSync对您而言,只有当它可以确定这样做是安全的时候。

这个小程序:

use std::cell::Cell;
use std::sync::atomic::AtomicUsize;

fn ensure_sync<T: Sync>(_: T) {}

struct Automatic(AtomicUsize);

impl Automatic {
fn new() -> Automatic { Automatic(AtomicUsize::new(0)) }
}

fn main() {
ensure_sync(AtomicUsize::new(0));
ensure_sync(Automatic::new());
ensure_sync(Cell::new(0));
}

仅在 Cell::new(0) 上出现错误线,AutomaticSync因为它的所有字段都是 Sync .


关于 Foo , Rc既不是 Sync也不Send ,所以实际上编译器不会为你实现。

可以FooSync

相信1是这样。只要没有其他操作添加到对不可变引用进行操作的模块。现在或将来。

可以FooSend

我同意你的结论,但我认为你错过了另一种修改 Cell 的方法: drop .

所以,确实,您似乎想出了一个类型 Sync而不是 Send ,通过使用基础类型 Send而不是 Sync .这可能是我的 Nerd 感觉,我觉得很有趣:)

1 处理unsafe时代码,我永远不确定任何事情。很容易自欺欺人地认为某事是安全的,仅仅是因为一个微小的细节没有引起注意。

关于multithreading - 这个稍作修改的 Rc<()> 是 Sync,而不是 Send,对吧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41846177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com