在下面的代码中,我试图实现一个运行 shell 命令并获取stdio
,stderr
并返回代码的程序。我正在按照此处boost process
建议的async
模式使用它。
namespace bp = boost::process;
class Process {
public:
Process(std::string & cmd, const int timeout);
void run();
private:
void timeout_handler();
const std::string command;
const int timeout;
bool killed;
bool stopped;
std::string stdOut;
std::string stdErr;
int returnStatus;
boost::asio::io_service ios;
boost::process::group group;
boost::asio::deadline_timer deadline_timer;
};
Process::Process(std::string & cmd, const int timeout):
command(cmd),
timeout(timeout),
deadline_timer(ios)
{}
void Process::timeout_handler()
{
if (stopped)
return;
if (deadline_timer.expires_at() <= boost::asio::deadline_timer::traits_type::now())
{
std::cout << "Time Up!" << std::endl;
group.terminate();
std::cout << "Killed the process and all its decendents" << std::endl;
killed = true;
stopped = true;
deadline_timer.expires_at(boost::posix_time::pos_infin);
}
deadline_timer.async_wait(std::bind(&Process::timeout_handler, this));
}
void Process::run()
{
std::future<std::string> dataOut;
std::future<std::string> dataErr;
bp::child c(command, bp::std_in.close(), bp::std_out > dataOut, bp::std_err > dataErr, ios, group);
deadline_timer.expires_from_now(boost::posix_time::seconds(timeout));
deadline_timer.async_wait(std::bind(&Process::timeout_handler, this));
ios.run();
c.wait();
stdOut = dataOut.get();
stdErr = dataErr.get();
returnStatus = c.exit_code();
}
int main(int argc, char** argv)
{
if(argc < 2)
{
std::cout << "Usage: \na.out <command>" << std::endl;
exit(1);
}
std::vector<std::string> arguments(argv + 1, argv + argc);
std::string command;
for( const auto & tok : arguments)
{
command += tok + " ";
}
std::cout << command << std::endl;
Process p(command, 10);
p.run();
return 0;
}
现在,上面的代码只有在deadline_timer
过期后才返回。我想要的是,如果子进程在计时器到期之前完成,或者它(连同它派生的所有子进程)应该终止,它应该退出。请指出我代码中的错误。