zoukankan      html  css  js  c++  java
  • Golang使用os/exec时产生僵尸(defunct)进程

    • 最近使用golang的os/exec包来启动chrome,并定时杀死chrome。在使用过程中发现系统产生了僵尸进程(defunct process)
    • 启动的代码:
    cmd := exec.Command(chromePath, args[:]...)
    if err := cmd.Start(); err != nil {
    	return err
    }
    
    • kill的代码
    if err := cmd.Process.Kill(); err != nil {
    	return err
    }
    
    • 僵尸进程在百度百科,维基百科都有基本的解释。以下内容摘自百度百科:
    • 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源
    • 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程。 但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程
    • 僵尸进程的避免
      ⒈ 父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
      ⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
      ⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
    • 根据百科的内容很容易联想到,即便使用golang的标准库,在kill进程后,父进程仍需调用wait方法回收资源。而实际上golang的os/exec包是提供了该方法的。只要确保在父进程杀死子进程后,可以调用到如下逻辑,即可在golang管理进程的过程中避免产生僵尸进程。
    • 需要注意的是,wait函数是阻塞的,即在子进程没有结束前,父进程调用该方法将会被阻塞,使用时需注意。
    if err := cmd.Wait(); err != nil { //避免僵尸进程
    	return err
    }
    
  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/lianggx6/p/12626107.html
Copyright © 2011-2022 走看看