有没有一种方法可以“检查和设置”`std :: cell :: Cell`的值?

3
我正在寻找一个能够编译成神奇的 cmpxchg 指令的东西。在查看文档后,我没有找到任何可以实现这一点的 Cell 相关内容。
也许这是一个反模式?
代码:
在查看代码后,我添加了以下内容到 Cell 的实现中,以查看它是否起作用。
pub fn cmp_and_set(&self, old: T, new: T) -> T {
    unsafe {
        ::intrinsics::atomic_cxchg(self.value.get(), old, new)
    }
}
// ^ there are many many reasons why this is not so great
// this is just an example of what I'm looking for

简单用法

fn main() {
    let c0 = Cell::new(10);
    let val0 = c0.cmp_and_set(11, 5);
    assert_eq!(c0.get(), 5);
    let val1 = c0.cmp_and_set(10, 42);
    assert_eq!(c0.get(), 42);
}

据我所知,对于非常基本的情况,它可以工作,但是仍然有很多原因导致特定的实现不够出色。我编辑标准库以获得我想要的结果,这意味着我肯定在尝试实现某种反模式。
背景:
这是从重新阅读《Rust编程语言》中的以下内容引起的:使用此包装器仍然可能违反自己的不变量,因此在使用时要小心。如果一个字段被包装在Cell中,则这是一个很好的指示符,表明数据块是可变的,并且在您第一次读取它和打算使用它之间可能不会保持相同。

2
我对这段文字的理解更多地是:“Cell 具有内部可变性,因此接受 &Cell 的方法可能会改变它。这与其他 Rust 代码不同,其中 mut 关键字清楚地表示它将发生更改。”我的理解并不是“某个线程随时可能更改值”。换句话说,我认为您不需要原子检查或任何复杂的东西。实际上,我把它看作“Cell 像传统面向对象语言中的任何其他对象一样运作,这可能会让人感到困惑,所以要小心!” - Shepmaster
啊!你说得对。出于某种原因,我认为Cell实现了同步。 - Daniel Robertson
1个回答

4
TL;DR: 不需要使用 Compare and Set,因为这并不必要。
对于仅有两个或更多的参与者同时修改对象的情况下,Compare and Set 才有价值。
虽然 Cell 允许内部的可变性,但它并不是线程安全的。因此,在尝试同时修改对象的情况下,并不会出现两个参与者同时进行修改的情况。
因此,可以使用 get()、compare 和 set(),如果它适合您的需求。只要您不调用其他代码,就没有人会在您的 get()set() 之间更改该值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接