在指向结构的指针上使用 AtomicPtr::compare_exchange 时的行为是啥?
Posted
技术标签:
【中文标题】在指向结构的指针上使用 AtomicPtr::compare_exchange 时的行为是啥?【英文标题】:What is the behavior of AtomicPtr::compare_exchange when used on a pointer to a struct?在指向结构的指针上使用 AtomicPtr::compare_exchange 时的行为是什么? 【发布时间】:2021-05-25 06:37:24 【问题描述】:compare_exchange
的这种用法会产生已定义的行为吗?
use std::sync::atomic::AtomicPtr, Ordering;
struct Dummy
foo: i64,
bar: i64,
fn main()
let ptr = &mut Dummy foo: 1, bar: 2 ;
let some_ptr = AtomicPtr::new(ptr);
let other_ptr = &mut Dummy foo: 10, bar: 10 ;
let value = some_ptr.compare_exchange(ptr, other_ptr, Ordering::SeqCst, Ordering::Relaxed);
如果已定义,定义的行为是什么? Rust 会在 x86_64 等受支持的架构上使用双宽 CAS 进行上述操作吗?
【问题讨论】:
AtomicPtr::compare_exchange
仅比较和交换 指针,它是 64 位的,没有理由与 CAS 进行双精度操作。
是的,我对 compare_exchange 的理解是错误的。感谢您清理它
【参考方案1】:
compare_exchange
的这种用法会产生已定义的行为吗?
除非编译器或标准库中出现错误,否则安全的 Rust 永远不会导致 C 和 C++ 意义上的未定义行为。此外,创建和操作指针始终是安全的,它只是取消引用它们或将它们转换为需要显式 unsafe
的引用,因为程序员需要提供编译器无法验证的保证。当然,对安全函数的特定调用是否符合您的预期是另一回事。
如果定义了,定义的行为是什么?
行为是由文档指定的:将some_ptr
指向的地址与ptr
指向的地址进行比较,如果它们匹配,some_ptr
会自动更新为指向@987654326 提供的地址@。在任何一种情况下都会返回前一个指针。由于您的代码从ptr
初始化some_ptr
,并且没有创建可以更改它的线程,因此将导致some_ptr
指向other_ptr
提供的地址,并返回ptr
。
Rust 会在 x86_64 等受支持的架构上使用双宽度 CAS 进行上述操作吗?
AtomicPtr::compare_exchange()
只比较和交换指针,它与usize
一样宽(现代硬件上为 64 位),没有理由使用双宽 CAS。
但我想我理解混乱是如何产生的:compare_exchange
的文档谈到了指针的值。这个“值”不是指向数据的值,它只是底层的*mut T
指针,它只代表一个内存地址。就像AtomicBool
的值是bool
,AtomicPtr
的值是一个指针。
如果文档使用“
【讨论】:
以上是关于在指向结构的指针上使用 AtomicPtr::compare_exchange 时的行为是啥?的主要内容,如果未能解决你的问题,请参考以下文章