【问题标题】:How to create future that completes once tokio::process::Child has exited without closing stdin一旦 tokio::process::Child 退出而不关闭 stdin,如何创建完成的未来
【发布时间】:2021-01-14 15:49:39
【问题描述】:

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

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

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)
    }
}

【问题讨论】:

  • 也许我看到这种行为是因为我将 (Option::take) ChildStdinChild 中取出并留下None 代替它?
  • 查看source code for the exit method,我认为这可能是文档中的问题...我在关闭stdin的代码中看不到任何内容...
  • 我在#tokio-dev 上询问了上述问题,我的 MRE 应该崩溃,但代码中确实存在问题,wait 在 1.0.1 中没有关闭 stdin

标签: rust tokio


【解决方案1】:

所以这个问题的答案是Option::takeChildStdin out of tokio::process::Child,如Github issue 中所述。在这种情况下,wait 不会关闭stdin,程序员有责任不造成死锁。

上面的 MRE 没有失败有两个原因:(i) 我从 tokio::process::Child 中取出了 ChildStdin 和 (ii) 即使我没有取出它,它仍然不会因为以下原因而关闭将在this pull request 中修复的代码错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多