MST

星途 面试题库

面试题:Rust字符串:跨线程安全与生命周期管理

在一个多线程Rust程序中,有多个线程需要共享一个字符串数据。如何确保字符串的跨线程安全,同时合理管理其生命周期?请从 `Sync` 和 `Send` 特性、`Arc` 和 `Mutex` 等角度详细阐述实现思路,并给出关键代码示例。
39.6万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. SyncSend 特性

    • Send 特性:在Rust中,实现了 Send 特性的类型可以安全地跨线程发送。大部分基本类型,如 i32String 等都实现了 Send 特性。这意味着可以将这些类型的数据通过通道(channel)等方式发送到其他线程。
    • Sync 特性:实现了 Sync 特性的类型可以安全地在多个线程间共享。例如,&TT: Sync 时,&T 也实现了 Sync 特性。这使得多个线程可以拥有指向同一个数据的不可变引用。
  2. ArcMutex 的作用

    • Arc(原子引用计数)Arc 用于在堆上分配数据,并允许多个 Arc 实例指向同一个数据,通过引用计数来管理数据的生命周期。当最后一个 Arc 实例被销毁时,数据才会被释放。它主要用于线程安全地共享数据,因为 Arc 实现了 SendSync 特性。
    • Mutex(互斥锁)Mutex 用于保护数据,确保同一时间只有一个线程可以访问数据。它通过锁定机制来实现这一点,当一个线程获取了 Mutex 的锁,其他线程就必须等待锁被释放才能访问数据。Mutex 也实现了 SendSync 特性。
  3. 实现思路

    • 为了在多线程中安全地共享字符串数据,我们可以使用 Arc<Mutex<String>>Arc 确保字符串数据可以在多个线程间安全共享,Mutex 确保同一时间只有一个线程可以修改字符串。
    • 当一个线程需要读取或修改字符串时,它首先需要获取 Mutex 的锁。如果锁不可用,线程会被阻塞,直到锁可用。
  4. 关键代码示例

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

fn main() {
    let shared_string = Arc::new(Mutex::new(String::from("initial value")));

    let mut handles = vec![];
    for _ in 0..10 {
        let string_clone = Arc::clone(&shared_string);
        let handle = thread::spawn(move || {
            let mut string = string_clone.lock().unwrap();
            string.push_str(" modified by thread");
        });
        handles.push(handle);
    }

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

    let final_string = shared_string.lock().unwrap();
    println!("Final string: {}", final_string);
}

在上述代码中:

  • 首先创建了一个 Arc<Mutex<String>> 类型的 shared_string
  • 然后在一个循环中创建了10个线程,每个线程克隆一份 Arc 并获取 Mutex 的锁,修改字符串。
  • 主线程等待所有子线程完成后,再次获取锁并打印最终的字符串。