exec.Command僵尸进程问题

uuid · · 667 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## 问题 exec.Command是Go标准库提供了一个可以很容易地运行外部命令的方法,但是如果使用不当会容易出现僵尸进程的问题。 > 僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。 exec.Command执行的方法有两种,一种是直接调用Run()方法: ```go cmd := exec.Command("ls") cmd.Run() ``` 另外一种是用start方法 ```go cmd := exec.Command("ls")cmd.Start() cmd.Wait() ``` 区别在于 - Run()方法是在“ls”执行完后才返回 - Start()方法则是异步的,方法调用完并不是代表结束,需要配合cmd.Wait() Run和Start方式本质是一样的,查看Run()方法的代码,可以看到实际上也是调用Start后直接调用Wait(),等待Wait返回 ```go func (c *Cmd) Run() error { if err := c.Start(); err != nil { return err } return c.Wait() } ``` Wait的功能就是获取子进程的状态,如果不调用就会导致僵尸进程的,可以用一下例子验证: 执行 ```go 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僵尸进程问题 | 艺术码农的小栈](https://itart.cn/blogs/2021/practice/exec-command-zombie.html)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

667 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传