exec.Command僵尸进程问题

问题

exec.Command是Go标准库提供了一个可以很容易地运行外部命令的方法,但是如果使用不当会容易出现僵尸进程的问题。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

exec.Command执行的方法有两种,一种是直接调用Run()方法:

cmd := exec.Command("ls")
cmd.Run()

另外一种是用start方法

cmd := exec.Command("ls")cmd.Start()
cmd.Wait()

区别在于

  • Run()方法是在“ls”执行完后才返回

  • Start()方法则是异步的,方法调用完并不是代表结束,需要配合cmd.Wait()

Run和Start方式本质是一样的,查看Run()方法的代码,可以看到实际上也是调用Start后直接调用Wait(),等待Wait返回

func (c *Cmd) Run() error {
   if err := c.Start(); err != nil {
      return err
   }
   return c.Wait()
}

Wait的功能就是获取子进程的状态,如果不调用就会导致僵尸进程的,可以用一下例子验证:

执行

func main() {
   cmd := exec.Command("ls")
   cmd.Start()
   time.Sleep(100* time.Second)
}

查询僵尸进程(mac)

✗ ps -A -ostat,ppid,pid,command | grep -e '^[Zz]'
Z+   24625 24626 (ls) // 结果出现一个僵尸进程

结论

cmd.Start()后要记得调用Wait方法,否则会出现僵尸进程

原文:

exec.Command僵尸进程问题 | 艺术码农的小栈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值