golang exec.Command导致很多失效的进程

xre*_*ren 2 go pptp

我正在使用golang调用pppd,然后过一会儿将其杀死。但是,以这种方式我得到了许多已失效的过程。

这就是我运行pppd的方式

exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()
Run Code Online (Sandbox Code Playgroud)

这就是我杀死它的方法。

exec.Command("sh", "-c", "pkill pppd").CombinedOutput()
Run Code Online (Sandbox Code Playgroud)

然后我得到了很多

root     31541 23536  0 10:54 ?        00:00:00 [pppd] <defunct>
root     31929 23356  0 10:55 ?        00:00:00 [pptpgw] <defunct>
root     31933 23356  0 10:55 ?        00:00:00 [pptpcm] <defunct>
root     31940 23356  0 10:55 ?        00:00:00 [pppd] <defunct>
root     31993 23536  0 10:55 ?        00:00:00 [pptpgw] <defunct>
root     31997 23536  0 10:55 ?        00:00:00 [pptpcm] <defunct>
root     31998 23536  0 10:55 ?        00:00:00 [pppd] <defunct>
root     32012 23356  0 10:55 ?        00:00:00 [pptpgw] <defunct>
root     32016 23356  0 10:55 ?        00:00:00 [pptpcm] <defunct>
root     32017 23356  0 10:56 ?        00:00:00 [pppd] <defunct>
root     32070 23536  0 10:56 ?        00:00:00 [pptpgw] <defunct>
root     32074 23536  0 10:56 ?        00:00:00 [pptpcm] <defunct>
root     32075 23536  0 10:56 ?        00:00:00 [pppd] <defunct>
root     32083 23356  0 10:56 ?        00:00:00 [pptpgw] <defunct>
root     32087 23356  0 10:56 ?        00:00:00 [pptpcm] <defunct>
root     32089 23356  0 10:56 ?        00:00:00 [pppd] <defunct>
root     32131 23536  0 10:57 ?        00:00:00 [pptpgw] <defunct>
root     32135 23536  0 10:57 ?        00:00:00 [pptpcm] <defunct>
root     32148 23536  0 10:57 ?        00:00:00 [pppd] <defunct>
root     32160 23356  0 10:57 ?        00:00:00 [pptpgw] <defunct>
root     32164 23356  0 10:57 ?        00:00:00 [pptpcm] <defunct>
root     32165 23356  0 10:57 ?        00:00:00 [pppd] <defunct>
root     32177 23536  0 10:57 ?        00:00:00 [pptpgw] <defunct>
root     32181 23536  0 10:57 ?        00:00:00 [pptpcm] <defunct>
Run Code Online (Sandbox Code Playgroud)

我如何避免失效的过程。

Mil*_*sen 5

这些“僵尸”进程是在进程完成时创建的,但父进程尚未通过wait系统调用读取其退出状态。

我想您需要做的就是调用(*Cmd).Wait()您创建的每个命令结构。显然,这不会像您想的那样简单,因为您可能要Wait等到第二个命令完成后才调用第一个命令。


编辑:正如在注释中指出的,(*Cmd).CombinedOutput()调用(*Cmd).Run(),其中调用(*Cmd).Wait()...所以以上是错误的。在这种情况下,真正的答案是由于某种原因sh并没有清除,因此解决方案是切掉男中音,然后像这样进行通话:

exec.Command("pppd", "call", "vpn").CombinedOutput()
Run Code Online (Sandbox Code Playgroud)

那会教我下次更仔细地阅读文档...

  • 实际上.CombinedOutput()已经调用了wait()。我猜想wait()只在等待sh而不是sh创建的子进程。你知道如何解决这个问题吗? (2认同)