设计思路
- 使用原子类型:在 Rust 中,
std::sync::atomic::AtomicBool
是一个适合作为停止标志的原子类型。它提供了原子操作,能在多线程环境下安全地读写值。
- 线程间共享:通过
Arc
(原子引用计数)来共享这个原子标志,使得多个线程都能访问和检查这个标志。
- 停止信号处理:主线程或其他控制线程可以设置这个原子标志为
true
来发出停止信号。工作线程在合适的时机检查这个标志,一旦发现标志为 true
,就停止当前工作。
关键代码实现
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
fn main() {
// 创建原子停止标志
let stop_flag = Arc::new(AtomicBool::new(false));
let stop_flag_clone = Arc::clone(&stop_flag);
// 创建线程
let handle = thread::spawn(move || {
while!stop_flag_clone.load(Ordering::SeqCst) {
// 线程工作内容
println!("Thread is working...");
thread::sleep(std::time::Duration::from_millis(100));
}
println!("Thread stopped.");
});
// 主线程等待一段时间后发出停止信号
thread::sleep(std::time::Duration::from_secs(2));
stop_flag.store(true, Ordering::SeqCst);
// 等待线程结束
handle.join().unwrap();
}
竞态条件处理
- 原子操作:
AtomicBool
的 load
和 store
方法使用了内存序(Ordering
)来保证原子操作的可见性和顺序性。例如 Ordering::SeqCst
提供了顺序一致性,确保所有线程以相同的顺序观察到这些操作。这样避免了由于不同线程对内存读写顺序不一致导致的竞态条件。
- 共享引用管理:通过
Arc
来共享 AtomicBool
,Arc
内部的引用计数机制是线程安全的,确保多个线程可以安全地共享这个停止标志,不会出现悬垂指针等问题,进一步避免竞态条件。