4

exec.Command僵尸进程问题

 2 years ago
source link: https://studygolang.com/articles/35287
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

exec.Command僵尸进程问题

uuid · 大约5小时之前 · 23 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    

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僵尸进程问题 | 艺术码农的小栈


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK