MST
星途 面试题库

面试题:Rust字符串在并发场景中的基本应用

在Rust中,假设你有多个线程需要共享一个字符串并进行读写操作,如何利用Rust的并发原语和字符串类型确保线程安全?请给出代码示例并简要解释。
27.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

在Rust中,要让多个线程共享一个字符串并进行读写操作,可以使用Arc(原子引用计数)和Mutex(互斥锁)或RwLock(读写锁)来确保线程安全。以下是使用ArcMutex的示例:

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

fn main() {
    // 创建一个Arc<Mutex<String>>
    let shared_string = Arc::new(Mutex::new(String::from("Hello, ")));

    let mut handles = vec![];
    for _ in 0..3 {
        let shared_string_clone = Arc::clone(&shared_string);
        let handle = thread::spawn(move || {
            // 锁定Mutex以获取字符串的可变引用
            let mut s = shared_string_clone.lock().unwrap();
            s.push_str("world! ");
        });
        handles.push(handle);
    }

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

    // 主线程中打印最终结果
    println!("{}", shared_string.lock().unwrap());
}

代码解释

  1. Arc<Mutex<String>>
    • Arcstd::sync::Arc)是原子引用计数指针,用于在多个线程间安全地共享数据。
    • Mutexstd::sync::Mutex)是互斥锁,用于保护共享数据,确保同一时间只有一个线程可以访问数据。Mutex提供了lock方法,该方法返回一个Result,成功时返回一个MutexGuard智能指针,这个指针拥有对数据的独占访问权。
  2. 线程创建
    • 在循环中,通过Arc::clone复制Arc指针,以便每个线程都能持有一份指向共享数据的引用。
    • 每个线程通过shared_string_clone.lock().unwrap()获取Mutex的锁,并获得字符串的可变引用,然后修改字符串。
  3. 等待线程结束
    • 使用join方法等待所有线程完成,确保所有修改都已完成。
  4. 打印最终结果
    • 主线程中再次获取锁并打印最终的字符串。

如果读操作远多于写操作,也可以使用RwLock(读写锁)来提高效率,示例如下:

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

fn main() {
    let shared_string = Arc::new(RwLock::new(String::from("Hello, ")));

    let mut handles = vec![];
    for _ in 0..3 {
        let shared_string_clone = Arc::clone(&shared_string);
        let handle = thread::spawn(move || {
            // 读取时使用read方法获取共享引用
            let s = shared_string_clone.read().unwrap();
            println!("Read: {}", s);
        });
        handles.push(handle);
    }

    let write_handle = thread::spawn(move || {
        // 写入时使用write方法获取独占引用
        let mut s = shared_string.write().unwrap();
        s.push_str("world! ");
    });

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

    // 主线程中打印最终结果
    println!("{}", shared_string.read().unwrap());
}

RwLock解释

RwLock允许同一时间有多个线程进行读操作,但只允许一个线程进行写操作。read方法用于获取共享(只读)引用,write方法用于获取独占(可写)引用。这样在读多写少的场景下可以提高并发性能。