rust - `mem::swap` ing a `Mutex<T>` 真的安全吗?

标签 rust

一个简单的例子:

use std::mem;
use std::sync::{Mutex};

fn main() {
    let mut orig = Mutex::new(vec![1, 2, 3]);
    let mut other = Mutex::new(vec![]);
    mem::swap(&mut orig, &mut other);
    println!("{:?}", other);
}

根据 Rust 的说法,这个程序是绝对安全的。然而,swap(或replace)的实现并不试图锁定任何东西。来自source :

#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping(&*x, &mut t, 1);
        ptr::copy_nonoverlapping(&*y, x, 1);
        ptr::copy_nonoverlapping(&t, y, 1);

        // y and t now point to the same thing, but we need to completely
        // forget `t` because we do not want to run the destructor for `T`
        // on its value, which is still owned somewhere outside this function.
        forget(t);
    }
}

MutexAtomic 变量上使用非同步访问似乎会带来麻烦,那么这安全吗?如果是,为什么?

最佳答案

MutexSync,意思是允许多个线程同时访问同一个对象。首先使跨线程共享单个对象成为可能的类型(Arc,还有全局变量)需要确保它们共享的对象是 Sync 到确保完整性。

但是,这并不能避免 Rust 的其他别名规则。具体来说,在任何给定时间只能存在一个变量的 mut 借用,并且它的存在必须阻止对该变量的任何其他访问。使共享成为可能的事情也必须确保这一点。 Arc 通过简单地从不将 mut 引用传递给它的指针来做到这一点;您只能获取非mut 引用。这就是 Mutex::lock 采用 &self 的原因:必须可以在非 mut 引用上调用它。同样,Atomic*::store 和所有其他操作方法都采用 &self。另一方面,static mut 变量只能在不安全的代码中访问,程序员负责维护保证。

mem::swap 需要 mut 引用。当编译器允许您将两个 Mutex 对象传递给 swap 时,这意味着您从一开始就从未与其他线程共享互斥量 - 您既没有将它们放入 Arc,它们也不是 static(不是 mut)或 static mut(除非您使用的是不安全代码)。

因此,swap 是安全的,因为您是在一个线程中进行的。

关于rust - `mem::swap` ing a `Mutex<T>` 真的安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35652404/

相关文章:

postgresql - 如何使用 Diesel 更新现有对象? "` T : Identifiable` is not satisfied"

generics - 具有通用参数类型的函数

rust - 如何将HashSet <&String>转换为HashSet <String>

c++ - 内存栅栏和内存栅栏一样吗?

methods - 如何在 Rust 中将对象用作其自身方法的参数?

rust 在 x86_64 机器上编译 x86 库

string - 拆分字符串并返回片段

iterator - 如果另一个特征是否实现,函数如何有条件地回退到特征?

rust - 你如何避免 cast::forget() 在 rust 中的内存泄漏?

string - Rust 中的 r #""# 运算符是什么?