面试题答案
一键面试基本原理
Rust 的线程停放机制允许线程暂停执行(停放),并在稍后被唤醒继续执行。这一机制基于操作系统提供的线程同步原语,如互斥锁(Mutex)和条件变量(Condvar)来实现。
主要结构体
parking_lot::Mutex
:- 互斥锁用于保护共享资源,确保同一时间只有一个线程可以访问特定的数据。在停放机制中,它用于保护与线程停放相关的状态信息。例如,它可以保护一个标志位,用于表示线程是否已被停放。
parking_lot::Condvar
:- 条件变量用于线程间的同步,它允许一个线程等待某个条件满足,而其他线程可以通知等待的线程条件已经满足。在停放机制中,条件变量用于通知停放的线程可以被唤醒。
主要方法及协同工作
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(); });
- 线程调用
unpark
方法:- 其他线程调用
unpark
方法来唤醒停放的线程。调用unpark
时,线程会获取互斥锁,检查要唤醒的线程是否已停放(通过检查相关标志位)。如果已停放,则通过条件变量通知等待的线程,然后释放互斥锁。被唤醒的线程会重新获取互斥锁,从park
调用处继续执行。 - 例如:
{ let _lock = mutex.lock(); if *parked.lock() { condvar.notify_one(); } }
- 其他线程调用
通过 park
和 unpark
方法,以及 Mutex
和 Condvar
结构体的协同工作,Rust 实现了线程的暂停与唤醒功能。