gpt4 book ai didi

rust - 为什么我不能使用存储在结构中的线程句柄?

转载 作者:行者123 更新时间:2023-12-04 13:06:35 25 4
gpt4 key购买 nike

我想实现一个执行器。我想将线程句柄存储在一个结构中,以便稍后加入它,等待线程正常停止。

但是当我尝试调用 join() 方法时出现错误。我想知道原因以及如何解决这个问题。

struct Executor{
tx:Sender<Box<dyn Send + Fn()>>,
t:JoinHandle<()>,
}
impl Executor {
fn new()->Self{
let (tx, rx) = mpsc::channel::<Box<dyn Send + Fn()>>();
let handle = thread::spawn(move || {
loop{
//TODO: check stop flag
rx.recv().unwrap()();
}
});

let ins = Executor{tx:tx, t:handle};
ins
}
fn sender(&self)->Sender<Box<dyn Send + Fn()>>{
self.tx.clone()
}
fn join(&self){
self.t.join().unwrap();
}
}

错误:

error[E0507]: cannot move out of `self.t` which is behind a shared reference
--> src\main.rs:77:9
|
77 | self.t.join().unwrap();
| ^^^^^^ move occurs because `self.t` has type `JoinHandle<()>`, which does not implement the `Copy` trait

最佳答案

你不能那样使用它,因为 join() 方法取得句柄的所有权,从而将其移出结构。

pub fn join(self) -> Result<T>

但是如果您将它从结构中取出,那么该内存位置将包含无效数据并且您的结构将处于无效状态。假设你调用 join()一次,句柄被移出结构,然后您尝试调用 join()第二次 - 第二次调用将访问未初始化的内存,即 UB。

所以你必须处理没有JoinHandle的情况当下。这可以通过使用 Option<JoinHandle> 来完成。 :

struct Executor{
tx:Sender<Box<dyn Send + Fn()>>,
t: Option<JoinHandle<()>>,
}

然后您的连接方法可以安全地从结构中取出句柄:

fn join(&mut self){
if let Some(handle) = self.t.take(){
handle.join().unwrap();
}
}

正如@user4815162342 在评论中指出的那样,在这种特殊情况下,最好使您的 join()接受 self而不是使用 Option<JoinHandle<>>为了防止有人在执行程序停止后使用它:

fn join(self){
self.t.join().unwrap();
}

关于rust - 为什么我不能使用存储在结构中的线程句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69189818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com