MST
星途 面试题库

面试题:Rust中多线程里happens - before关系的基础体现

在Rust的多线程编程中,假设有两个线程,线程A对一个共享变量x进行赋值操作,线程B读取这个共享变量x的值。请使用Rust代码示例展示如何通过合适的同步机制(如`Mutex`)来确保线程A对x的赋值操作happens - before线程B对x的读取操作,并解释代码中是如何体现这种happens - before关系的。
27.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let shared_data = Arc::new(Mutex::new(0));

    let data_clone = Arc::clone(&shared_data);
    let handle_a = thread::spawn(move || {
        let mut data = data_clone.lock().unwrap();
        *data = 42;
    });

    let data_clone = Arc::clone(&shared_data);
    let handle_b = thread::spawn(move || {
        let data = data_clone.lock().unwrap();
        println!("Read value: {}", *data);
    });

    handle_a.join().unwrap();
    handle_b.join().unwrap();
}

解释

  1. Mutex的作用
    • Mutex(互斥锁)用于保护共享变量x(这里用Arc<Mutex<i32>>包装的0)。只有获得锁的线程才能访问和修改共享变量。
  2. Happens - before关系体现
    • 在线程A中,let mut data = data_clone.lock().unwrap();获取锁,然后进行赋值*data = 42;,在释放锁之前对共享变量的修改对其他线程是不可见的。
    • 在线程B中,let data = data_clone.lock().unwrap();获取锁,此时它能看到线程A在释放锁之前对共享变量的修改。由于线程A先获取锁,修改数据,然后释放锁,线程B后获取锁读取数据,这就建立了线程A的赋值操作happens - before线程B的读取操作的关系。
    • 调用join方法等待线程结束,确保线程A在主线程中先于线程B执行完成,进一步保证了这种happens - before关系。