【问题标题】:Multi-threaded communication with an external process in RustRust 中与外部进程的多线程通信
【发布时间】:2020-02-24 06:51:51
【问题描述】:

这里是生锈新手。

我想启动一个外部长时间运行的进程,并通过 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】:

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

    要使用来自线程的数据,您只有两个选择:

    • 将对象的所有权(独占)授予线程,即使用move || 闭包,之后不要尝试从主线程或任何其他线程使用该对象。

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

    当编译器说你需要一个“静态生命周期”时,忽略它。出于所有实际目的,这意味着“不允许引用”。

    【讨论】:

      猜你喜欢
      • 2018-04-09
      • 2017-08-07
      • 2013-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 2012-09-16
      • 1970-01-01
      相关资源
      最近更新 更多