How to query a child process status regularly

与世无争的帅哥 提交于 2021-01-28 07:38:16

问题


I have spawned a child process using Rust's Command API.

Now, I need to watch this process for a few seconds before moving on because the process may die early. On success, it should run "forever", so I can't just wait.

There's a nightly feature called try_wait which does what I want, but I really don't think I should run Rust nightly just for this!

I think I could start a new thread and keep it waiting forever or until the process dies... but I would like to not hang my process with that thread, so maybe run the thread as a daemon might be a solution...

Is this the way to go or is there a nicer solution?


回答1:


Currently, if you don't want to use the nightly channel, there's a crate called wait-timeout (thanks to @lukas-kalbertodt for the suggestion) that adds the wait_timeout function to the std::process::Child trait.

It can be used like this:

let cmd = Command::new("my_command")
    .spawn();

match cmd {
    Ok(mut child) => {
        let timeout = Duration::from_secs(1);

        match child.wait_timeout(timeout) {
            Ok(Some(status)) => println!("Exited with status {}", status),
            Ok(None) => println!("timeout, process is still alive"),
            Err(e) => println!("Error waiting: {}", e),
        }
    }
    Err(err) => println!("Process did not even start: {}", err);
}

To keep monitoring the child process, just wrap this into a loop.

Notice that using Rust's nightly try_wait(), the code would looks nearly identical (so once it makes into the release branch, assuming no further changes, it should be very easy to move to that), but it will block for the given timeout even if the process dies earlier than that, unlike with the above solution:

let cmd = Command::new("my_command")
    .spawn();

match cmd {
    Ok(mut child) => {
        let timeout = Duration::from_secs(1);
        sleep(timeout); // try_wait will not block, so we need to wait here
        match child.try_wait() {
            Ok(Some(status)) => println!("Exited with status {}", status),
            Ok(None) => println!("timeout, process is still alive"),
            Err(e) => println!("Error waiting: {}", e),
        }
    }
    Err(err) => println!("Process did not even start: {}", err);
}


来源:https://stackoverflow.com/questions/43705010/how-to-query-a-child-process-status-regularly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!