Rust中修改持有值与可变借用引用为何安全?多场景安全逻辑分析
非并发场景下的代码安全性
你给出的这段代码完全安全,能正常编译的核心原因是不存在同一时间的重叠访问,并不满足数据竞争的三个前提条件。
你注意看数据竞争定义里的「at the same time」,指的是多个指针的活跃生命周期重叠、访问时间段重叠,而不是代码行的先后排列。在这段同步执行的代码里,你调用change_aaa(&mut aaa)时传入的可变引用,生命周期仅覆盖函数调用执行的全程,函数返回后这个可变引用就直接失效了。后续你执行aaa = 2的时候,当前上下文中没有任何其他活跃的引用指向aaa,两个写入操作是严格先后执行的,没有任何重叠,自然不会触发不安全规则。
并发场景下的代码安全性
你没办法直接把change_aaa(&mut aaa)放到子线程执行,就是Rust安全设计刻意做的限制,不是你用法的问题。std::thread::spawn创建的子线程生命周期是独立的,要求传入的闭包满足'static生命周期约束,而你传入的&mut aaa是栈上的临时引用,生命周期只和当前栈帧绑定,编译器会直接拒绝这种用法,从根源上避免子线程还在操作aaa、主线程已经释放了aaa或者同时修改aaa的情况出现。
如果你确实需要多线程修改同一个值,需要使用配套的同步原语,比如用Arc<Mutex<i32>>包裹你要修改的值,跨线程传递Arc的克隆实例,访问值前先获取锁,满足「有同步机制控制访问」的要求,编译器才会允许编译通过。
内容的提问来源于stack exchange,提问作者calvin
相关产品推荐
相关产品推荐

