MST

星途 面试题库

面试题:Rust静态生命周期全局变量在多线程环境下的应用

假设你在一个多线程Rust程序中需要使用一个静态生命周期的全局变量,该变量需要在多个线程间共享且保证线程安全,你会如何实现?说明所使用的同步原语及其原理,并给出相关代码。
46.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 实现方式
    • 在Rust中,对于多线程环境下静态生命周期的全局变量,且要保证线程安全,可以使用std::sync::Mutexstd::sync::RwLock等同步原语。这里以Mutex为例,Mutex(互斥锁)是一种同步原语,它通过提供一种机制来保证同一时间只有一个线程可以访问被保护的数据。当一个线程获取了Mutex的锁,其他线程就必须等待,直到该线程释放锁。
  2. 代码示例
use std::sync::{Mutex, Arc};
use std::thread;

// 定义一个静态的全局变量,使用Arc和Mutex来保证线程安全
static GLOBAL_VARIABLE: Arc<Mutex<i32>> = Arc::new(Mutex::new(0));

fn main() {
    let mut handles = vec![];
    for _ in 0..10 {
        let global_variable = Arc::clone(&GLOBAL_VARIABLE);
        let handle = thread::spawn(move || {
            let mut num = global_variable.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // 打印最终的全局变量值
    println!("Final value: {}", *GLOBAL_VARIABLE.lock().unwrap());
}

在上述代码中:

  • 首先定义了一个静态的GLOBAL_VARIABLE,类型为Arc<Mutex<i32>>Arc(原子引用计数)用于在多个线程间共享数据,Mutex用于保证线程安全的访问。
  • main函数中,创建了10个线程,每个线程获取GLOBAL_VARIABLE的克隆,并尝试获取Mutex的锁,获取成功后对内部的i32值加1 。
  • 最后等待所有线程执行完毕,打印出GLOBAL_VARIABLE的最终值。

如果使用RwLock,其原理是允许多个线程同时进行读操作,但只允许一个线程进行写操作。写操作会独占锁,在读操作进行时,写操作会被阻塞,反之亦然。代码实现如下:

use std::sync::{RwLock, Arc};
use std::thread;

// 定义一个静态的全局变量,使用Arc和RwLock来保证线程安全
static GLOBAL_VARIABLE: Arc<RwLock<i32>> = Arc::new(RwLock::new(0));

fn main() {
    let mut handles = vec![];
    for _ in 0..10 {
        let global_variable = Arc::clone(&GLOBAL_VARIABLE);
        let handle = thread::spawn(move || {
            let mut num = global_variable.write().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // 打印最终的全局变量值
    println!("Final value: {}", *GLOBAL_VARIABLE.read().unwrap());
}

在这个代码中,使用RwLock替代了Mutexwrite方法用于获取写锁,read方法用于获取读锁。由于这里只是简单的写操作,使用RwLock在这种场景下和Mutex效果类似,但如果有大量读操作的场景,RwLock能提高并发性能。