MST
星途 面试题库

面试题:Rust线程停放机制的基本原理

请简述Rust线程停放机制的基本原理,包括涉及到的主要结构体和方法,以及它们是如何协同工作来实现线程的暂停与唤醒的。
40.8万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

基本原理

Rust 的线程停放机制允许线程暂停执行(停放),并在稍后被唤醒继续执行。这一机制基于操作系统提供的线程同步原语,如互斥锁(Mutex)和条件变量(Condvar)来实现。

主要结构体

  1. parking_lot::Mutex
    • 互斥锁用于保护共享资源,确保同一时间只有一个线程可以访问特定的数据。在停放机制中,它用于保护与线程停放相关的状态信息。例如,它可以保护一个标志位,用于表示线程是否已被停放。
  2. parking_lot::Condvar
    • 条件变量用于线程间的同步,它允许一个线程等待某个条件满足,而其他线程可以通知等待的线程条件已经满足。在停放机制中,条件变量用于通知停放的线程可以被唤醒。

主要方法及协同工作

  1. park 方法
    • 线程调用 park 方法来停放自身。当一个线程调用 park 时,它首先会获取与停放机制相关的互斥锁。然后,它会将自己标记为已停放,并通过条件变量进入等待状态,同时释放互斥锁。这样,其他线程就可以修改共享状态。
    • 例如:
    use parking_lot::{Mutex, Condvar};
    let mutex = Mutex::new(());
    let condvar = Condvar::new();
    let parked = Mutex::new(false);
    std::thread::spawn(move || {
        let _lock = mutex.lock();
        *parked.lock() = true;
        condvar.wait(mutex.lock()).unwrap();
    });
    
  2. unpark 方法
    • 其他线程调用 unpark 方法来唤醒停放的线程。调用 unpark 时,线程会获取互斥锁,检查要唤醒的线程是否已停放(通过检查相关标志位)。如果已停放,则通过条件变量通知等待的线程,然后释放互斥锁。被唤醒的线程会重新获取互斥锁,从 park 调用处继续执行。
    • 例如:
    {
        let _lock = mutex.lock();
        if *parked.lock() {
            condvar.notify_one();
        }
    }
    

通过 parkunpark 方法,以及 MutexCondvar 结构体的协同工作,Rust 实现了线程的暂停与唤醒功能。