You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程通过同一指针执行原子操作是否属于Rust未定义行为

Rust无锁算法中AtomicPtr操作的合法性疑问

我正在Rust中实验无锁算法与免等待算法,发现AtomicPtr非常实用,可通过比较交换、交换等指针操作实现无锁数据结构。但我在阅读Rust的指针别名规则时看到如下说明:

违反指针别名规则:&mut T 和 &T 遵循LLVM的作用域noalias模型,除非 &T 包含UnsafeCell。
变更不可变数据:const项内的所有数据都是不可变的。此外,所有通过共享引用访问的数据、或不可变绑定拥有的数据都是不可变的,除非该数据包含在UnsafeCell内。

另外规则中关联的LLVM文档相关内容如下:

这表示在函数执行期间,基于参数或返回值的指针访问的内存位置,不会被不基于该参数/返回值的指针访问。该保证仅适用于函数执行期间以任何方式被修改的内存位置。

从上述规则来看,原子操作确实会修改指针指向的数据,但Rust和LLVM文档都没有明确将原子操作列为规则例外,我不确定原子操作是否属于定义明确的行为。
因此想知道以下代码在Rust中是否属于未定义行为:

use std::sync::atomic::{AtomicUsize, AtomicPtr, Ordering};
use std::thread;

struct Point {
    x: AtomicUsize,
    y: AtomicUsize
}

impl Point {
    fn new_ptr() -> *mut Point {
        Box::into_raw(Box::new(Point{x: AtomicUsize::new(0), y: AtomicUsize::new(0)}))
    }
}

fn main() {
    let point = Point::new_ptr();
    let cont = AtomicPtr::new(point);
    let handle = thread::spawn(move || {
        let r = unsafe {  cont.load(Ordering::SeqCst).as_ref().unwrap() };
        for _ in 0..10000 {
            r.x.fetch_add(1, Ordering::SeqCst);
        }
    });
    unsafe {  point.as_ref().unwrap().x.fetch_add(1, Ordering::SeqCst); }
    handle.join().unwrap();
    unsafe {
        drop(Box::from_raw(point));
    }
}

该代码及其小幅变体都可以正常编译运行、符合预期,但我不确定当前写法是否属于未定义行为,也希望确认该合法用法未来不会被限制或修改。


回答

你提供的代码不属于Rust未定义行为,属于合法的原子操作用法,且该用法在Rust内存模型的保障范围内,未来不会被无理由限制或修改,具体原因如下:

  • Rust标准库中的所有原子类型(包括AtomicUsize、AtomicPtr等)内部都包裹了UnsafeCell,你引用的别名规则中明确说明:如果&T内部包含UnsafeCell,则不受LLVM作用域noalias模型约束,允许通过共享引用修改内部数据,完全匹配你代码中的使用场景。
  • LLVM的noalias规则本身就不适用于同步原子操作访问的内存:原子操作属于线程间同步原语,LLVM的优化流程会特殊处理这类操作,不会对跨线程的原子访问应用noalias相关的优化,避免破坏同步逻辑。
  • 你的代码所有操作均符合Rust unsafe代码的约定:
    • 所有对Point结构体字段的修改都是通过原子类型自带的方法实现,没有直接修改不可变引用指向的非UnsafeCell数据
    • 多个线程持有Point的共享引用同时访问原子字段的行为是被明确允许的,原子操作本身保障了并发访问的内存安全性
    • 最终通过Box::from_raw回收内存的逻辑正确,不存在野指针、双重释放等问题

内容的提问来源于stack exchange,提问作者Josh Weinstein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:36:04