1

执行摘要:我需要一种方法来确定我通过 _spawnl 生成并正在使用 _pipe 中的 FD 进行通信的 Windows 进程是否已经死亡。

细节:

我正在使用 Windows 中的低级 CRT 函数(_eof,_read)与通过调用 _spawnl(使用 P_NOWAIT)标志生成的进程进行通信。我正在使用 _pipe 创建文件描述符以与这个生成的进程进行通信,并在命令行上将这些描述符(FD #)传递给它。

值得一提的是,我不控制生成的过程。对我来说这是一个黑匣子。

事实证明,我们生成的进程偶尔会崩溃。我试图通过检测崩溃来使我的代码对此具有健壮性。不幸的是,我看不到这样做的方法。在我看来,如果进程终止,对其中一个描述符的 _eof 或 _read 调用将返回错误状态 (-1),这似乎是合理的。

不幸的是,事实并非如此。描述符似乎有自己的生命,独立于生成的进程。因此,即使另一端的进程已经死了,我用来与之通信的文件描述符上也没有错误状态。

我已经获得了嵌套进程的 PID(从 _spanwnl 调用返回),但我没有看到任何可以用它做的事情。我的代码运行良好,除了一件事。我无法检测到生成的进程是否只是忙于计算我的答案或已经死亡。

如果我可以使用来自 _pipe 和 _spawnl 的信息来确定生成的进程是否已死,我会很高兴。

非常欢迎提出建议。

提前致谢。

更新:我找到了一个相当简单的解决方案并将其添加为选定的答案。

4

3 回答 3

1

如果您希望能够检测到该过程已退出,则必须向上移动食物链。本机 CreateProcess() Win32 API 可以返回一个 HANDLE,您可以在 WaitForSingleObject() API 中使用它来等待或测试进程是否已退出。如果你能得到 PID,你可以使用 OpenProcess() 来得到你需要的 HANDLE。

另一种方法是使用 _P_WAIT 使其成为同步调用。那将需要一个线程。

于 2010-01-22T20:18:38.753 回答
1

请参阅 如何知道 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;
  }
}
于 2010-04-09T16:48:38.103 回答
0

感谢 nobugz 提供了很多好的建议。我最终没有走他的“向上移动食物链”的路线,所以我把它写成一个单独的答案,但这很大程度上是他反馈的结果。

我使用我现有的调用 spawnl。事实证明这是可能的,因为当使用 P_NOWAIT 模式调用时,返回值实际上与 OpenProcess 相同。这很令人困惑,因为 spawnl 的返回类型为 intptr_t,而 OpenProcess 的返回类型为 HANDLE。但它们是等价的(至少基于我的测试)。

知道这一点,我仍然没有走出困境。我需要一种可靠的方法来确定进程是否仍在运行。我使用进程句柄(例如GetModuleBaseName)进行的所有各种调用都成功了,即使进程已经死了。

最终,我求助于调用 GetProcessId(使用我的进程句柄)来获取进程 ID,然后调用 EnumerateProcesses 并挖掘从它返回的结果,以查看是否有任何正在运行的进程共享相同的进程 ID。

我承认使用更高级别的 API(如 nobugz 建议的那样)可能是一般要走的路。在我的例子中,我已经让所有代码工作了,只需要确定嵌套进程是否仍在运行,所以我采取了一种极简主义的方法。

再次感谢 nobugz 提供的所有有用建议。

于 2010-01-25T21:52:53.460 回答