- 使用
AtomicBool
实现停止标志:
Atomic
类型适用于简单的原子操作,对于停止标志这种布尔类型的值,AtomicBool
是一个很好的选择。它可以在多线程环境下进行无锁的读写操作,性能较高且资源消耗低。
- 读操作使用
load
方法,写操作使用store
方法。
- 使用
Mutex
的情况:
- 如果停止标志的操作不仅仅是简单的读写,例如可能需要在修改标志的同时进行一些复杂的逻辑处理,那么
Mutex
可以提供更通用的互斥访问。
- 通过
MutexGuard
来确保同一时间只有一个线程可以访问和修改停止标志。但是Mutex
是基于锁的机制,相比Atomic
类型会有一定的性能开销。
- 处理死锁情况:
- 死锁原因:死锁通常发生在多个线程互相等待对方释放锁的情况下。例如,线程A持有锁L1并等待锁L2,而线程B持有锁L2并等待锁L1。
- 预防方法:
- 锁顺序一致:确保所有线程以相同的顺序获取锁。例如,如果线程可能需要获取锁L1和锁L2,那么所有线程都应该先获取L1,再获取L2。
- 超时机制:在获取锁时设置超时。如果在指定时间内没有获取到锁,线程可以放弃当前操作并尝试重新获取,从而避免无限期等待。
Mutex
类型本身不支持超时,但可以通过std::sync::Condvar
结合Mutex
来实现类似功能。
- 简单的多线程停止标志实现代码片段(使用
AtomicBool
):
use std::sync::Arc;
use std::thread;
use std::sync::atomic::{AtomicBool, Ordering};
fn main() {
let stop_flag = Arc::new(AtomicBool::new(false));
let stop_flag_clone = stop_flag.clone();
let handle = thread::spawn(move || {
while!stop_flag_clone.load(Ordering::SeqCst) {
// 线程工作逻辑
println!("线程正在运行...");
thread::sleep(std::time::Duration::from_millis(100));
}
println!("线程接收到停止信号,即将退出");
});
// 主线程等待一段时间后设置停止标志
thread::sleep(std::time::Duration::from_secs(2));
stop_flag.store(true, Ordering::SeqCst);
handle.join().unwrap();
}
- 简单的多线程停止标志实现代码片段(使用
Mutex
):
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let stop_flag = Arc::new(Mutex::new(false));
let stop_flag_clone = stop_flag.clone();
let handle = thread::spawn(move || {
loop {
let flag = stop_flag_clone.lock().unwrap();
if *flag {
break;
}
drop(flag); // 手动释放锁,提高性能
// 线程工作逻辑
println!("线程正在运行...");
thread::sleep(std::time::Duration::from_millis(100));
}
println!("线程接收到停止信号,即将退出");
});
// 主线程等待一段时间后设置停止标志
thread::sleep(std::time::Duration::from_secs(2));
let mut flag = stop_flag.lock().unwrap();
*flag = true;
handle.join().unwrap();
}