我有一段代码可以执行一个过程并检索结果。
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 上读取输出而不会使父级死锁?
最佳答案
如果 child 没有退出,那么对 fgets() 的调用将不会退出,因此您需要解决 child 没有退出的原因。这种情况最可能的原因是子进程挂了,因为它没有标准输入。
如果这是问题所在,您可以通过将管道模式更改为“rw”来解决它。您通常不需要对额外的管道做任何事情,它只需要在那里。
(正如您在评论中提到的,该问题也可以通过使用命令 shell 重定向来为 child 提供 NUL
作为标准输入的句柄来解决。)
关于c++ - 在 Windows 上执行流程并获取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31639168/