我使用golang来调用pppd,然后在一段时间后将其杀死。但是我以这种方式得到了很多失效的过程。
这是我运行pppd的方式
exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()
这就是我杀了它的方式。
exec.Command("sh", "-c", "pkill pppd").CombinedOutput()
然后我得到了很多这个
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>
如何避免失效的过程。
答案 0 :(得分:4)
当进程完成时会创建这些"zombie" processes,但父进程尚未通过wait
系统调用读取其退出状态。
我猜你需要做的只是在你创建的每个命令结构上调用(*Cmd).Wait()
。显然,这可能不像你想的那么直截了当,因为你可能不想在第一个命令上调用Wait
,直到第二个命令完成为止。
编辑:正如评论中指出的那样,(*Cmd).CombinedOutput()
调用(*Cmd).Run()
,调用(*Cmd).Wait()
......所以上述内容是错误的。在这种情况下,真正的答案是,由于某些原因,sh
不能清理,所以解决办法就是切断midle man并按照这样的方式进行调用:
exec.Command("pppd", "call", "vpn").CombinedOutput()
我会教我下次再仔细阅读文档......
答案 1 :(得分:0)
取消命令的一种更简单的方法是使用exec.CommandContext。 e.g。
ctx, cancel := context.WithCancel(context.Background())
exec.CommandContext(ctx, "pppd", "call", "vpn").CombinedOutput()
// in some other goroutine...
cancel()
也许这会解决你的僵尸问题?
答案 2 :(得分:0)
在新线程中运行子进程
go exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()
杀死子进程
exec.Command("pkill", "pppd").CombinedOutput().CombinedOutput()