与Rust中的外部进程进行多线程通信

问题描述 投票:1回答:1

这里是一个生锈的新手。

我想启动一个外部的长期运行的过程,并通过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
multithreading process rust lifetime
1个回答
0
投票

您不能将&self(临时借用)传递给线程,因为在引用不再有效之后该线程可能会继续运行。

对于使用线程中的数据,您只有两个选择:

  • 将对象的所有权(是排他的)授予线程,即使用move ||闭包,以后不要再从主线程或任何其他线程中使用该对象。

  • Arc中包装对象以获得共享的线程安全所有权,并将克隆发送到线程(使用Arc::clone便宜,并且共享基础数据)。]]

  • [当编译器说您需要“静态生存期”时,请忽略它。出于所有实际目的,它表示“不允许引用”。

© www.soinside.com 2019 - 2024. All rights reserved.