[英]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.