共享线程数组

gek*_*mad 1 arrays multithreading rust

slaves_th是一个共享的线程数组,下面我想join在每个线程上调用,但编译器抛出错误slaves_th.lock().unwrap()不是迭代器。

let slaves_th: Arc<Mutex<Vec<JoinHandle<()>>>> = Arc::new(Mutex::new(Vec::new()));

for _ in 0..8 {
    slaves_th
        .lock()
        .unwrap()
        .push(thread::spawn(move || println!("Hi")));
}

for th in slaves_th.lock().unwrap() {
    //   ^^^^^^^^^^^^^^^^^^^^^^^^^^ `MutexGuard<'_, Vec<JoinHandle<()>>>` is not an iterator
    match th.join() {
        Ok(_) => {}
        Err(_) => {
            println!("err join");
            ()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

caf*_*e25 5

问题是,就像编译器告诉你的那样,它MutexGuard没有实现IntoIterator,也不能实现,因为它是按值IntoIterator::into_iter获取的self,但 aMutexGuard仅具有对Mutex.

但是您可以将您的集合转变为Iterator允许您迭代它们的集合。因为您必须按值获取元素(JoinHandle::join需要拥有self),所以您最好的选择是使用Vec::drain

for th in slaves_th.lock().unwrap().drain(..) {
Run Code Online (Sandbox Code Playgroud)

take()您也可以使用1,不同之处在于它会消耗Vec之前包含的内容Mutex并将其替换为新的。drain因此,它释放了分配的内存:

for th in std::mem::take(&mut *slaves_th.lock().unwrap()) {
Run Code Online (Sandbox Code Playgroud)

1正如@user4815162342指出的。

  • 但是“Vec”确实实现了“Default”,无论 @ChayimFriedman 的内容如何。在这里,如果你想释放已占用的内存,可以使用“take”,如果想重用它,可以使用“drain(..)”。 (2认同)