我有一段代码,它执行一个进程并检索结果。
namespace {
FILE* really_popen(const char* cmd, const char* mode) {
#ifdef _MSC_VER
return _popen(cmd, mode);
#else
return popen(cmd, mode);
#endif
}
void really_pclose(FILE* pipe) {
#ifdef _MSC_VER
_pclose(pipe);
#else
pclose(pipe);
#endif
}
std::string ExecuteProcess(std::string cmd) {
FILE* pipe = really_popen(cmd.c_str(), "r");
if (!pipe) throw std::runtime_error("Could not invoke command " + cmd);
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
really_pclose(pipe);
return result;
}
}
这对我来说在Linux上运行得很好,但在Windows上,它有一个可怕的死锁习惯--似乎fgets
再也不会回来了。我已经查看了CRT源代码,fgets
最终委托给了永远不会返回的ReadFile
。
如果我从命令行调用该命令,它将在一秒钟内返回。
如何在不死锁父程序的情况下读取Windows上的输出?
发布于 2015-07-26 14:38:46
如果子程序还没有退出,那么对fget()的调用就不会退出,所以您需要解决为什么子程序没有退出。在这种情况下,最有可能的原因是孩子挂起是因为没有标准输入。
如果这是问题所在,您可以通过将管道模式更改为"rw“来解决这个问题。你通常不需要用额外的管道做任何事情,它只需要在那里。
(正如您在注释中提到的,这个问题也可以通过使用命令shell重定向来将NUL
的句柄作为标准输入来解决。)
https://stackoverflow.com/questions/31639168
复制相似问题