Rust遍历Mutex包裹的线程数组时迭代器错误问题求助
问题解决:遍历Mutex包裹的Vec并调用线程join
错误原因
slaves_th.lock().unwrap()返回的是MutexGuard<'_, Vec<JoinHandle<()>>>类型,这是一个保护内部Vec的智能指针,它本身没有实现IntoIterator trait,因此无法直接在for循环中迭代。
解决方案1:获取内部Vec的引用进行遍历
通过&*解引用MutexGuard得到内部Vec的引用,或者直接调用.iter()方法获取迭代器,这样就能遍历每个JoinHandle的引用并调用join:
use std::sync::{Arc, Mutex}; use std::thread; fn main() { let slaves_th: Arc<Mutex<Vec<thread::JoinHandle<()>>>> = Arc::new(Mutex::new(Vec::new())); for _ in 0..8 { let slaves_clone = Arc::clone(&slaves_th); slaves_clone .lock() .unwrap() .push(thread::spawn(move || println!("Hi"))); } // 方式1:通过&*解引用获取Vec引用 for th in &*slaves_th.lock().unwrap() { match th.join() { Ok(_) => {} Err(_) => { println!("err join"); } } } // 方式2:调用iter()方法获取迭代器 // for th in slaves_th.lock().unwrap().iter() { // match th.join() { // Ok(_) => {} // Err(_) => { // println!("err join"); // } // } // } }
解决方案2:取出内部Vec后遍历(推荐)
如果后续不再需要slaves_th中的Vec,可以用.drain(..)将Vec中的元素全部取出,这样MutexGuard会立即释放锁,避免在join阻塞期间长时间持有锁(join可能等待线程结束,持有锁会导致其他线程无法访问该Mutex):
use std::sync::{Arc, Mutex}; use std::thread; fn main() { let slaves_th: Arc<Mutex<Vec<thread::JoinHandle<()>>>> = Arc::new(Mutex::new(Vec::new())); for _ in 0..8 { let slaves_clone = Arc::clone(&slaves_th); slaves_clone .lock() .unwrap() .push(thread::spawn(move || println!("Hi"))); } // 取出所有handle,释放锁 let handles = slaves_th.lock().unwrap().drain(..).collect::<Vec<_>>(); for th in handles { match th.join() { Ok(_) => {} Err(_) => { println!("err join"); } } } }
内容的提问来源于stack exchange,提问作者gekomad
相关产品推荐
相关产品推荐

