[英]RUST: Reference to a TCPListener and TcpStream from one thread to a Struct in another thread
[英]Copying a struct for use on another thread
我有一个结构:
struct MyData {
x: i32
}
我想在此结构上异步启动长操作。
我的第一次尝试是:
fn foo(&self) { //should return immediately
std::thread::Thread::spawn(move || {
println!("{:?}",self.x); //consider a very long operation
});
}
显然, cannot infer an appropriate lifetime due to conflicting requirements
,编译器cannot infer an appropriate lifetime due to conflicting requirements
因为self
可能位于堆栈框架上,因此无法保证操作在不同的堆栈框架上运行时就已经存在。
为了解决这个问题,我尝试制作一个self
的副本并将该副本提供给新线程:
fn foo(&self) { //should return immediately
let clone = self.clone();
std::thread::Thread::spawn(move || {
println!("{:?}",clone.x); //consider a very long operation
});
}
我认为这不能编译,因为现在clone
位于堆栈框架上,与以前类似。 我也尝试在线程内进行clone
,但出于同样的原因,它也无法编译。
然后我决定也许可以使用channel
将复制的数据推入线程中,这是基于以下理论: channel
可以神奇地在线程之间移动(复制?)堆栈分配的数据, 此示例在文档中提出 。 但是,编译器无法为此推断寿命:
fn foo(&self) { //should return immediately
let (tx, rx) = std::sync::mpsc::channel();
tx.send(self.clone());
std::thread::Thread::spawn(move || {
println!("{:?}",rx.recv().unwrap().x); //consider a very long operation
});
}
最后,我决定只是将我的结构显式复制到堆上,然后将Arc传递到线程中。 但即使在这里,编译器也无法确定生命周期:
fn foo(&self) { //should return immediately
let arc = std::sync::Arc::new(self.clone());
std::thread::Thread::spawn(move || {
println!("{:?}",arc.clone().x); //consider a very long operation
});
}
好吧,借支票员,我放弃。 我如何获得的一份self
到我新的线程?
我认为您的问题仅仅是因为您的结构没有派生Clone
特征。 您可以通过在结构的定义之前添加#[derive(Clone)]
来获取第二个示例进行编译和运行。
我在此处的编译器行为中不了解的是它尝试在此处使用的.clone()
函数。 您的结构确实没有实现Clone
特性,因此默认情况下不应具有.clone()
函数。
您也可以在你的函数取来考虑self
的价值 ,并让您的来电者决定是否应该克隆,或只是一招。
作为替代解决方案,您可以使用thread::scoped
并维护该线程的句柄。 这使线程可以保留引用,而无需将其复制到:
#![feature(old_io,std_misc)]
use std::thread::{self,JoinGuard};
use std::old_io::timer;
use std::time::duration::Duration;
struct MyData {
x: i32,
}
// returns immediately
impl MyData {
fn foo(&self) -> JoinGuard<()> {
thread::scoped(move || {
timer::sleep(Duration::milliseconds(300));
println!("{:?}", self.x); //consider a very long operation
timer::sleep(Duration::milliseconds(300));
})
}
}
fn main() {
let d = MyData { x: 42 };
let _thread = d.foo();
println!("I'm so fast!");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.