MST

星途 面试题库

面试题:Rust线程在并发服务器中的基础应用

在Rust编写的并发服务器场景下,简要描述如何使用`std::thread`创建新线程并传递数据,并且说明如何处理线程间可能出现的资源竞争问题,比如使用什么机制进行同步?
40.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

创建新线程并传递数据

在Rust中使用std::thread创建新线程并传递数据可以通过以下方式:

use std::thread;

fn main() {
    let data = String::from("Hello, thread!");

    let handle = thread::spawn(move || {
        println!("Thread received data: {}", data);
    });

    handle.join().unwrap();
}

在上述代码中:

  1. 定义了一个data变量,类型为String
  2. 使用thread::spawn创建新线程,并通过闭包捕获data。这里使用move关键字,它将data的所有权转移到新线程中。

处理线程间资源竞争问题及同步机制

  1. 互斥锁(Mutex)
    • 互斥锁用于保护共享资源,每次只允许一个线程访问。
    • 示例:
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

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

    println!("Final counter value: {}", *counter.lock().unwrap());
}
  • 在这个例子中,Arc<Mutex<i32>>用于在多个线程间共享计数器。Mutex确保每次只有一个线程能修改计数器的值。lock方法返回一个MutexGuard,它在作用域结束时自动释放锁。
  1. 读写锁(RwLock)
    • 当有多个线程频繁读取共享资源,而写操作较少时,使用读写锁更合适。它允许多个线程同时读,但只允许一个线程写。
    • 示例:
use std::sync::{Arc, RwLock};
use std::thread;

fn main() {
    let data = Arc::new(RwLock::new(String::from("initial data")));
    let mut handles = vec![];

    for _ in 0..3 {
        let data = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let read_data = data.read().unwrap();
            println!("Read data: {}", read_data);
        });
        handles.push(handle);
    }

    let data = Arc::clone(&data);
    let write_handle = thread::spawn(move || {
        let mut write_data = data.write().unwrap();
        *write_data = String::from("new data");
    });
    handles.push(write_handle);

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

    let final_data = data.read().unwrap();
    println!("Final data: {}", final_data);
}
  • 这里Arc<RwLock<String>>用于共享数据。读操作使用read方法获取RwLockReadGuard,写操作使用write方法获取RwLockWriteGuard
  1. 条件变量(Condvar)
    • 条件变量用于线程间的同步通信。一个线程可以等待某个条件满足,而其他线程可以通知等待的线程条件已经满足。
    • 示例:
use std::sync::{Arc, Mutex};
use std::sync::Condvar;
use std::thread;

fn main() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair2 = Arc::clone(&pair);

    let handle = thread::spawn(move || {
        let (lock, cvar) = &*pair2;
        let mut started = lock.lock().unwrap();
        *started = true;
        cvar.notify_one();
    });

    let (lock, cvar) = &*pair;
    let mut started = lock.lock().unwrap();
    while!*started {
        started = cvar.wait(started).unwrap();
    }
    println!("Condition met!");
    handle.join().unwrap();
}
  • 在这个例子中,一个线程等待条件变量cvar的通知,另一个线程设置条件并通知等待的线程。wait方法会释放锁并阻塞线程,直到收到通知。收到通知后,它重新获取锁并返回。