我有一段代码执行一个过程并检索结果。
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
最终将其委托(delegate)给ReadFile
,但它永远不会返回。如果我从命令行调用该命令,它将在一秒钟内返回。
如何在Windows上读取输出而不会死锁父级?
最佳答案
如果该子项尚未退出,则对fgets()的调用不会退出,因此您需要解决该子项未退出的原因。在这种情况下,最有可能的原因是 child 因为没有标准输入而被挂起。
如果那是问题,则可以通过将管道模式更改为“rw”来解决。您通常不需要对多余的管道做任何事情,只需要在那儿就可以了。
(正如您在注释中提到的,也可以通过使用命令 shell 重定向为子级提供NUL
的句柄作为标准输入来解决该问题。)