看起来,如果您通过exec.CmdStart()创建了一个子流程,则会立即填充Cmd.Process字段,但是Cmd.ProcessState字段将保持nil直到该流程退出。



如此看来,我在运行时仍无法实际检查Start()编码的进程的状态?

对我来说,在进程退出时设置ProcessState毫无意义。在这种情况下,有一个ProcessState.Exited()方法将始终返回true

因此,我尝试采用这种方法:cmd.Process.Pid字段在cmd.Start()之后立即存在,但是os.Process似乎没有提供任何机制来检查进程是否在运行。

os.FindProcess说:



这没有用–似乎没有办法从os.Process转换为os.ProcessState,除非您使用.Wait()破坏了整个目的(我想知道该过程是否正在运行,然后退出)。

最佳答案

我认为您在这里有两个合理的选择:

  • 派出一个goroutine,等待该进程退出。等待完成后,您知道该过程已退出。 (正面:很容易正确编码;负面:您将OS线程专用于等待。)
  • 在已发布的syscall.Wait4()上使用Pid。设置了Wait4syscall.WNOHANG会立即返回,并填写状态。

  • 如果有一个导出的oscmd函数为您完成了Wait4并填写了ProcessState,那可能会很好。您认为合适,可以提供WNOHANG,也可以不提供。但是没有。
    ProcessState.Exited()的重点是区分所有各种可能性,包括:
  • 进程正常退出(带有状态字节)
  • 进程由于接收到未处理的信号
  • 而死亡

    参见the stringer for ProcessState。请注意,比这两种方法有更多的可能性……仅似乎无法将其他方法变成ProcessState。对syscall.Wait的唯一调用似乎是:
  • syscall/exec_unix.go:失败的exec之后,在返回错误之前收集僵尸;和
  • os/exec_unix.go:调用p.blockUntilWaitable()之后。

  • 如果不是blockUntilWaitable,则exec_unix.gowait()实现变体可以使用syscall.Wait4调用syscall.WNOHANG,但blockUntilWaitable本身可确保这毫无意义(并且此wait的目标是无论如何都要等待退出)。

    10-04 23:34