rust 怎么与长期存活子进程获取输出 ?

下面的两个尝试代码都是:rust version :rustc 1.71.0

尝试1:

use std::io::{BufRead, BufReader};
use std::process::{Command, Stdio};
use std::thread;
use std::thread::sleep;
use std::time::Duration;

fn start_listener<T: 'static + Send + Fn(&str)>(cb: T) {
    let mut child = Command::new("jupyter")
        .arg("lab")
        .arg("--no-browser")
        // .arg("google.com")
        // .stdout(Stdio::inherit())
        .stdout(Stdio::piped())
        .spawn()
        .expect("Failed to start ping process");

    println!("Started process: {}", child.id());
    child.wait();

    thread::spawn(move || {
        let mut f = BufReader::new(child.stdout.unwrap());
        loop {
            let mut buf = String::new();
            match f.read_line(&mut buf) {
                Ok(_) => {
                    cb(buf.as_str());
                }
                Err(e) => println!("an error!: {:?}", e),
            }
        }
    });
}

fn main() {
    start_listener(|s| {
        println!("Got this back: {}", s);
    });

    sleep(Duration::from_secs(5));
    println!("Done!");
}

使用这个代码启动 jupyter lab 启动是正确,
但 rust 这边一直没有运行 println!("Got this back: {}", s); 是为什么?

没有接收到 子进程的输出?

尝试2

use std::io::{BufRead, BufReader, Write};
use std::process::{Command, Stdio};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Mutex;

use std::thread;
use std::thread::sleep;
use std::time::Duration;

fn start_process(sender: Sender<String>, receiver: Receiver<String>) {
    let child = Command::new("jupyter")
        .arg("lab")
        .arg("--no-browser")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("Failed to start process");

    println!("Started process: {}", child.id());

    thread::spawn(move || {
        let mut f = BufReader::new(child.stdout.unwrap());
        let mut stdin = child.stdin.unwrap();
        for line in receiver {
            stdin.write_all(line.as_bytes()).unwrap();
            let mut buf = String::new();
            match f.read_line(&mut buf) {
                Ok(_) => {
                    sender.send(buf).unwrap();
                    continue;
                }
                Err(e) => {
                    println!("an error!: {:?}", e);
                    break;
                }
            }
        }
    });
}

fn start_command_thread(mutex: Mutex<Sender<String>>) {
    thread::spawn(move || {
        let sender = mutex.lock().unwrap();
        sleep(Duration::from_secs(3));
        sender
            .send(String::from("Command from the thread\n"))
            .unwrap();
    });
}

fn main() {
    let (tx1, rx1) = channel();
    let (tx2, rx2) = channel();

    start_process(tx1, rx2);

    tx2.send(String::from("Command 1\n")).unwrap();
    start_command_thread(Mutex::new(tx2));

    for line in rx1 {
        println!("Got this back: {}", line);
    }
}

下面的仍然是没有执行,这是为什么

for line in rx1 {
        println!("Got this back: {}", line);
    }
阅读 1.5k
1 个回答
fn start_listener<T: 'static + Send + Fn(&str)>(cb: T) {
    let mut child = Command::new("jupyter")
        .arg("lab")
        .arg("--no-browser")
        .stdout(Stdio::piped())
        .spawn()
        .expect("Failed to start ping process");

    println!("Started process: {}", child.id());

    thread::spawn(move || {
        let mut f = BufReader::new(child.stdout.unwrap());
        loop {
            let mut buf = String::new();
            match f.read_line(&mut buf) {
                Ok(_) => {
                    cb(&buf);
                }
                Err(e) => println!("an error!: {:?}", e),
            }
        }
        child.wait().expect("Failed to wait on child");
    });
}

fn main() {
    start_listener(|s| {
        println!("Got this back: {}", s);
    });

    sleep(Duration::from_secs(5));
    println!("Done!");
}
fn start_process(sender: Sender<String>, receiver: Receiver<String>) {
    let mut child = Command::new("jupyter")
        .arg("lab")
        .arg("--no-browser")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        .spawn()
        .expect("Failed to start process");

    println!("Started process: {}", child.id());

    let child_stdout = child.stdout.take().unwrap();
    let child_stdin = child.stdin.take().unwrap();

    let sender_clone = sender.clone();
    thread::spawn(move || {
        let mut f = BufReader::new(child_stdout);
        loop {
            let mut buf = String::new();
            match f.read_line(&mut buf) {
                Ok(_) => {
                    sender_clone.send(buf).unwrap();
                }
                Err(e) => {
                    println!("an error!: {:?}", e);
                    break;
                }
            }
        }
    });

    thread::spawn(move || {
        let stdin = child_stdin;
        for line in receiver {
            stdin.write_all(line.as_bytes()).unwrap();
        }
    });
}

// ... (rest of your code)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进