douwei8672
douwei8672
2017-09-19 06:33
浏览 251
已采纳

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

I'm using golang to call pppd and then kill it after a while. However I got a lot of defunct proccesses in this way.

This is how I run pppd

exec.Command("sh", "-c", "pppd call vpn").CombinedOutput()

This is how I kill it.

exec.Command("sh", "-c", "pkill pppd").CombinedOutput()

Then I got a lot of this

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>

How can I avoid defunct processes.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • donglu3087
    donglu3087 2017-09-19 07:19
    已采纳

    These "zombie" processes are created when a process has finished, but the parent has not read their exit status via the wait system call.

    I would guess that all you need to do is call (*Cmd).Wait() on every command structure you create. Obviously This will be less straight forward than you may like, since you probably don't want to call Wait on the first command until after the second command is finished.


    EDIT: As is pointed out in the comments, (*Cmd).CombinedOutput() calls (*Cmd).Run(), which calls (*Cmd).Wait()... So the above is wrong. The real answer in this case is that for some reason sh isn't cleaning up, and so the solution is to cut out the midle man and do the call like so:

    exec.Command("pppd", "call", "vpn").CombinedOutput()
    

    That'll teach me to read the docs a little closer next time...

    点赞 评论
  • duanmeng1862
    duanmeng1862 2018-05-09 22:56

    A simpler way to cancel your command would be to use exec.CommandContext. e.g.

    ctx, cancel := context.WithCancel(context.Background())
    exec.CommandContext(ctx, "pppd", "call", "vpn").CombinedOutput()
    
    // in some other goroutine...
    cancel()
    

    Maybe this would solve your zombie problem?

    点赞 评论

相关推荐