执行摘要:我需要一种方法来确定我通过_spawnl生成的Windows进程是否与使用来自_pipe的FD进行通信已经死亡。
详细说明:
我正在使用Windows中的低级CRT函数(_eof,_read)与通过调用_spawnl(带有P_NOWAIT)标志生成的进程进行通信。我正在使用_pipe创建文件描述符来与这个衍生进程通信,并在命令行上将这些描述符(FD#)传递给它。
值得一提的是,我不控制衍生过程。这对我来说是一个黑盒子。
事实证明,我们产生的过程偶尔会崩溃。我试图通过检测崩溃使我的代码变得健壮。不幸的是,我看不到这样做的方法。对我来说,如果进程已经死亡,那么对其中一个描述符的_eof或_read调用将返回错误状态(-1)似乎是合理的。
不幸的是,事实并非如此。似乎描述符具有独立于生成过程的生命。因此,即使另一端的进程已经死亡,我也没有在我用来与之通信的文件描述符上获得错误状态。
我已经获得了嵌套进程的PID(从_spanwnl调用返回),但是我没有看到任何可以用它做的事情。除了一件事,我的代码工作得很好。我无法检测到衍生过程是否只是忙于给我一个答案或者已经死了。
如果我可以使用_pipe和_spawnl中的信息来确定生成的进程是否已经死亡,那么我将是金色的。
建议非常欢迎。
提前致谢。
更新:我找到了一个相当简单的解决方案,并将其添加为所选答案。
答案 0 :(得分:1)
如果您希望能够检测到该过程退出,您将不得不向上移动食物链。本机CreateProcess()Win32 API可以为您提供一个HANDLE,您可以在WaitForSingleObject()API中使用它来等待或测试进程是否已退出。如果你可以获得PID,你可以使用OpenProcess()来获得你需要的HANDLE。
另一种方法是使用_P_WAIT使其成为同步调用。这需要一个帖子。
答案 1 :(得分:1)
请参阅 How to know child process status and resource usage on windows?
你可以在spawnl返回的句柄上使用WaitForSingleObject;它对我来说很好。听起来你可能已经尝试过了,但也许我误解了你的回答。
生成进程并等待它完成而不使用_P_WAIT的示例代码:
HANDLE hProcess = (HANDLE) _spawnl(_P_NOWAIT, "slave.exe", "slave.exe", NULL);
while(1)
{
Sleep(100);
if (WaitForSingleObject(hProcess, 0) == WAIT_OBJECT_0)
{
break;
}
}
答案 2 :(得分:0)
感谢nobugz提供了很多好的建议。我最终没有采取“向上移动食物链”的路线,所以我把它写成一个单独的答案,但这很大程度上是他反馈的结果。
我使用了现有的spawnl调用。事实证明这是可能的,因为当使用P_NOWAIT模式调用时,返回值实际上与OpenProcess相同。这很令人困惑,因为spawnl的返回类型为intptr_t,而OpenProcess的返回类型为HANDLE。但它们是等价的(至少基于我的测试)。
知道了这一点,我仍然没有走出困境。我需要一种可靠的方法来确定进程是否仍在运行。即使进程已经死了,我使用进程句柄(例如GetModuleBaseName)进行的所有各种调用都会成功。
最终,我使用GetProcessId(使用我的进程句柄)来获取进程ID,然后调用EnumerateProcesses并挖掘从其返回的结果,以查看是否有任何正在运行的进程共享相同的进程ID。
我承认使用更高级别的API(如nobugz所建议的)可能是一般的方法。就我而言,我已经完成了所有代码的工作,只需确定嵌套进程是否仍在运行,所以我采用了极简主义的方法。
再次感谢nobugz提供所有有用的建议。