这里是一个生锈的新手。
我想启动一个外部的长期运行的过程,并通过Rust中多个线程的管道与之交谈。
我遇到了生命周期错误,无法找到适当的方法来取悦生命周期检查器。重组的方式有哪些?
请考虑以下示例:
use std::process::{Command, Stdio, ChildStdin};
use std::sync::Mutex;
use std::io::{Write};
use std::thread;
struct Element {
sink: Mutex<Option<ChildStdin>>
}
impl Element {
fn launch_process(&self) {
let child =
Command::new("sed").args(&["s/foo/bar/g"])
.stdin(Stdio::piped())
.spawn()
.unwrap();
let mut sink = self.sink.lock().unwrap();
*sink = child.stdin;
}
fn tx(&self, content: &[u8]) {
let mut sink = self.sink.lock().unwrap();
sink.as_mut().unwrap().write(content);
}
fn start_tx(&self) {
thread::spawn( || {
self.tx(b"foo fighters");
});
}
}
fn main() {
let e = Element {
sink: Mutex::new(None)
};
e.launch_process();
e.start_tx();
}
如果删除thread::spawn
位,那么一切都会按预期进行。设置thread::spawn
后,出现错误:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:28:24
|
28 | thread::spawn( || {
| ________________________^
29 | | self.tx(b"foo fighters");
30 | | });
| |_________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 27:5...
--> src/main.rs:27:5
|
27 | / fn start_tx(&self) {
28 | | thread::spawn( || {
29 | | self.tx(b"foo fighters");
30 | | });
31 | | }
| |_____^
= note: ...so that the types are compatible:
expected &&Element
found &&Element
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/main.rs:28:24: 30:10 self:&&Element]` will meet its required lifetime bounds
--> src/main.rs:28:9
|
28 | thread::spawn( || {
| ^^^^^^^^^^^^^
error: aborting due to previous error
您不能将&self
(临时借用)传递给线程,因为在引用不再有效之后该线程可能会继续运行。
对于使用线程中的数据,您只有两个选择:
将对象的所有权(是排他的)授予线程,即使用move ||
闭包,以后不要再从主线程或任何其他线程中使用该对象。
在Arc
中包装对象以获得共享的线程安全所有权,并将克隆发送到线程(使用Arc::clone
便宜,并且共享基础数据)。]]
[当编译器说您需要“静态生存期”时,请忽略它。出于所有实际目的,它表示“不允许引用”。