1

如何创建一个在 a 终止tokio::process::Child而不关闭的情况下完成的未来stdin。我知道try_wait可以测试一个进程是否在没有关闭的情况下终止stdin,但我希望这种行为具有未来的语义。

我试图为这个问题准备一个 MRE,我的代码stdin在调用后由于写入而出现恐慌,但我观察到的与等待方法wait的文档中所述的行为不匹配。我希望看到线路因管道破裂而崩溃,因为应该由.tokio::process::Childstdin.write_u8(24).await.unwrap();stdinwait

use tokio::{time, io::AsyncWriteExt}; // 1.0.1

use std::time::Duration;

#[tokio::main]
pub async fn main() {
    let mut child = tokio::process::Command::new("nano")
        .stdin(std::process::Stdio::piped())
        .spawn()
        .unwrap();
    
    let mut stdin = child.stdin.take().unwrap();

    let tasklet = tokio::spawn(async move {
        child.wait().await
    });

    // this delay should give tokio::spawn plenty of time to spin up
    // and call `wait` on the child (closing stdin)
    time::sleep(Duration::from_millis(1000)).await;

    // write character 24 (CANcel, ^X) to stdin to close nano
    stdin.write_u8(24).await.unwrap();

    match tasklet.await {
        Ok(exit_result) => match exit_result {
            Ok(exit_status) => eprintln!("exit_status: {}", exit_status),
            Err(terminate_error) => eprintln!("terminate_error: {}", terminate_error)
        }
        Err(join_error) => eprintln!("join_error: {}", join_error)
    }
}
4

1 回答 1

0

所以这个问题的答案是按照这个Github issueOption::take ChildStdin中的tokio::process::Child描述。在这种情况下,不会关闭并且程序员有责任不造成死锁。waitstdin

上面的 MRE 没有失败有两个原因:(i)我ChildStdin取出tokio::process::Child和(ii)即使我没有取出它,由于代码中的错误,它仍然不会关闭,将被修复在这个拉取请求中。

于 2021-01-14T16:48:27.100 回答