如何存储线程的JoinHandle以便稍后关闭它

luc*_*fer 13 rust

我试图在后台运行一个线程,然后更改 AtomicBool 来要求线程停止。为了确保线程正确停止,我想调用joinJoinHandle 的方法。

thread::sleep_ms如果我在设置 AtomicBool 后等待 () 一段时间,而不是调用 join ,线程就会正确关闭。但为了确保这一点,我想使用 join。或者有没有更好的方法来确保线程正确关闭?

use std::sync::Arc;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::thread::JoinHandle;

struct MyInner { s: String }

struct My {
    inner: Arc<Mutex<MyInner>>,
    close_thread: Arc<AtomicBool>,
    my_thread: JoinHandle<()>
}

impl MyInner {
    fn new(s: String) -> MyInner {
        MyInner {
            s: s
        }
    }
}

impl My {
    fn new(s: String) -> My {
        My {
            inner: Arc::new(Mutex::new(MyInner::new(s))),
            close_thread: Arc::new(AtomicBool::new(false)),
            my_thread: thread::spawn(move || {})
        }
    }

    fn stop_thread(&self) {
        self.close_thread.swap(true, Ordering::Relaxed);
        // ERROR!
        self.my_thread.join().expect("Couldn't join my_thread on the main thread");
    }

    fn start(&mut self) {
        let local_self = self.inner.clone();
        let close_thread = self.close_thread.clone();
        self.my_thread  = thread::spawn(move || {
            loop {
                if close_thread.load(Ordering::Relaxed) {
                    println!("Closing thread!");
                    return;
                }
                let gaurd = local_self.lock().unwrap();
                println!("Local self has value: {}", (*gaurd).s);
                std::mem::drop(gaurd);
                thread::sleep_ms(1000);
            }
        });
    }
}

fn main() {
    let mut m = My::new("blo".to_owned());
    m.start();
    thread::sleep_ms(2000);
    m.stop_thread();
    println!("Complete!");
}

Run Code Online (Sandbox Code Playgroud)

对于上面的代码,我得到错误:

error[E0507]: cannot move out of `self.my_thread` which is behind a shared reference
  --> src/main.rs:35:9
   |
35 |         self.my_thread.join().expect("Couldn't join my_thread on the main thread");
   |         ^^^^^^^^^^^^^^ move occurs because `self.my_thread` has type `std::thread::JoinHandle<()>`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)

我也尝试Arc在 JoinHandle 上使用,但即使在Arc::clone我收到相同的错误之后。