2

在等待 aboost::process::child时,你怎么知道它是否“优雅地”退出?

假设我创建了一个进程:

boost::process::child child( "myprg.exe", "5000" );
child.wait();
int res = child.exit_code();

myprg.exe 在哪里:

int main( int argc, char* argv[] )
{
    if ( argc == 2 )
    {
        boost::this_thread::sleep( boost::posix_time::milliseconds( atoi( argv[1] ) ) );
        return 1;
    }

    return 0;
}

注意:这是一个没有意义的 MCVE,我同意如果成功,main 应该返回 0。

我看到如果有人在等待时终止进程(child.terminate例如使用 Windows 进程管理器),child.exit_code()将返回 1。

那么,到底什么时候child.exit_code()是1,我怎么知道这是进程的主入口函数返回的值还是进程被杀死了呢?

是否保证 1 意味着进程被杀死?那么程序不应该返回 1 并保留这个退出代码来识别它被杀死并且没有干净退出的具体情况吗?

如果没有,boost::processAPI 是否提供了一些信息来了解进程是否干净地结束或被杀死?

4

2 回答 2

2

那么,到底什么时候child.exit_code()是1,我怎么知道这是进程的主入口函数返回的值还是进程被杀死了呢?

你不能。

是否保证 1 意味着进程被杀死?

这取决于。至于 Windows,根据这个答案,它将是 1,但它没有记录在任何地方。请注意,被终止进程的返回码由终止该进程的实例确定。对于 Boost 的终止函数,可以在 detail/windows/terminate.hpp 中找到:

inline void terminate(child_handle &p)
{
    if (!::boost::winapi::TerminateProcess(p.process_handle(), EXIT_FAILURE))
        boost::process::detail::throw_last_error("TerminateProcess() failed");

    ::boost::winapi::CloseHandle(p.proc_info.hProcess);
    p.proc_info.hProcess = ::boost::winapi::INVALID_HANDLE_VALUE_;
}

所以它EXIT_FAILURE总是返回,可能是 1。但是,可以让进程返回任何值。

为了区分您的进程是否以完全万无一失和可移植的方式优雅地终止,因此您必须实现自己的通信机制,而不仅仅是评估返回码。

于 2017-12-04T09:19:43.277 回答
0

您可以在子进程中设置错误处理程序以返回不同的退出代码。例如,从 STL 库添加std::set_terminate :

int main( int argc, char* argv[] )
{
    std::set_terminate([](){ exit(2); });
    if ( argc == 2 )
    {        
        boost::this_thread::sleep(boost::posix_time::milliseconds(atoi(argv[1])));
        return 1;
    }
    return 0;
}
于 2017-12-04T09:29:23.693 回答