为什么exec.Start()创建的进程如果其父节点被SIGINT杀死则退出?

时间:2013-10-08 09:05:46

标签: linux go signals exec fork

我在golang中发现了一个奇怪的问题。如果父程序被信号os.Interrupt中断,exec.Start()执行的程序将退出,而如果父程序正常退出则子程序不会退出。什么是这两个条件之间的区别?    例如:

package main

import "fmt"
import "os"
import "time"
import "os/exec"

func main(){
    cmd := exec.Command("sleep", "100000")
    cmd.Env = os.Environ()
    fmt.Println(cmd.Env)
    cmd.Start()

    time.Sleep(1e9*20)
    return
} 

如果我们没有中断主程序,在后来的情况下,sleep 100000的父级将在20秒后成为init process

2 个答案:

答案 0 :(得分:10)

发生的事情是,如果你发送一个进程SIGINT(例如os.Interrupt),同一process group中的所有进程也将获得该信号(包括子进程) - SIGINT将默认终止一个处理。

但是,如果父进程正常退出,而不是因为SIGINT或类似进程,则同一进程组中的进程不会获得任何信号 - 它将继续运行,但会被init进程采用。这不是Go特有的。

答案 1 :(得分:2)

我认为这是因为您使用的是Start而不是Run

  
    

开始启动指定的命令,但不等待它完成。

  

,而:

  
    

运行启动指定的命令并等待它完成。

  

因此Start只会在Go(父)进程退出时将进程切换到操作系统。