我试图写一个运行相关的方法,将启动一个新的线程,并保持运行。线程句柄保存在结构属性中,但我得到以下错误:
error[E0521]: borrowed data escapes outside of method
--> src\server\dispatcher.rs:33:27
|
28 | pub fn run(&mut self) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
...
33 | let main_thread = thread::spawn(move || loop {
| ___________________________^
34 | | match rx.try_recv() {
35 | | Ok(_) | Err(TryRecvError::Disconnected) => {
36 | | break;
... |
43 | | }
44 | | });
| | ^
| | |
| |__________`self` escapes the method body here
| argument requires that `'1` must outlive `'static`
|
我的代码:
pub fn run(&mut self) {
let (tx, rx) = mpsc::channel::<()>();
let packets = Arc::new(Mutex::new((&self.packets)));
let main_thread = thread::spawn(move || loop {
match rx.try_recv() {
Ok(_) | Err(TryRecvError::Disconnected) => {
break;
}
Err(TryRecvError::Empty) => {
let inside = packets.clone();
let qwe = packets.lock().unwrap();
}
}
});
self.main_thread = Some(main_thread);
}
3条答案
按热度按时间nvbavucw1#
解决方案可能会以某种方式使用thread::scope()。
您正在生成一个捕获
packets
的线程,其中包含self
的引用(指针)。对于编译器来说,当程序结束时,线程可能仍然在运行,在self
被释放很长时间后访问它。如果你从作用域中派生线程,编译器知道当作用域结束时它将被连接(等待)。您也可以在示波器末端发送停止信号。
有多种选择如何继续。您可以在外部创建范围并将其传递给
run()
。或者,您可以向run()
传递一个额外的lambda,其中包含创建线程后要执行的代码,因此您不必将任何特定于线程的内容存储到self
中。或者你不能在线程内部使用任何引用,并让它拥有通过队列的任何内容。k4emjkb12#
这与相关功能无关。
packets
捕获对self.packets
的引用。然后将其移动到线程中。但是你不能将引用移到线程中,除非它们引用静态数据,因为线程可能比它引用的任何东西都活得长。czq61nw13#
问题是你在一个新线程中借用了
self.packets
。借用检查器不知道这个线程将存活多久,但是self
的借用只对当前函数调用有效。您没有提供完整的代码示例,但简化一点,也许这是代表性的:
通过在struct字段上将共享数据设置为
Arc
,没有借用-只有Arc
的克隆:这是因为线程没有从
self
借用任何东西。