subprocess
subprocess copied to clipboard
Support non-blocking calls
(Continued from reddit)
For asynchronous command execution, there's two scenarios to consider.
First, running a command in the background with one or more of its stdin/stdout/stderr connected to an iostream. Might be worth looking into Boost.Process's pipe streams and buffers as an example of a fairly lightweight way to provide such streams. You still need a way to get a command's exit status when it finishes running (Just getting EOF on a pipe isn't enough).
Second, the case where you just want to capture the output in a string. My idea for this (Which can also be used for the exit status of the first case and possibly even in executing pipelines of multiple commands) is to have a run_async()
method that returns a future that, when complete, gives you an object with the captured stdout/stderr (If any), exit status, etc.
It'd look something like
std::future<result> status = command.run_async();
while (status.wait_for(std::chrono::seconds::zero) != std::future::ready) {
// Do something else
}
auto res = status.get();
std::cout << res.stdout() << '\n';
As you are designing the async API, here are a few thoughts that came up:
- Long-running pipes will delay the final result and in realtime applications, users are often interested in processing chunks of data as they flow in. It would be nice to have something like a
span<const byte>
orstring_view
abstraction to process data as it arrives, e.g., in 64k blocks. - From a dependency perspective, a hard requirement on Boost would rule us out as user. If you go down the Boost.Process route, it would be great to keep it optional.
Work in progress at https://github.com/shawnw/subprocess/tree/async_promises
(At the moment just uses futures for waiting for processes to exit in command::run()
.