如何杀死子进程?
我有一个长时间运行的应用程序,它使用“exec.Command”启动一个新进程:
// ...I am a long running application in the background
// Now I am starting a child process, that should be killed togeter with the parent application.
cmd := exec.Command("sh", "-c", execThis)
// create a new process group
// cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}现在,如果我杀死<pid of long running application in the background>,它不会杀死子进程--你知道怎么做吗?
发布于 2021-03-15 15:09:58
这里有很多东西要拆散。
首先,是操作系统本身所做的工作。然后,一旦我们知道操作系统是什么和它做什么,就会有程序做什么。
操作系统所做的显然是依赖于操作系统的。不过,POSIX口味的OSes有两种kill:普通kill和基于进程组的kill,或称killpg。这个函数的基函数是唯一向整个进程组发送信号的函数;普通的kill只向单个进程发送信号。
当程序从https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap11.html运行时,键盘信号(^C、^Z等)被发送到该控制终端的前台进程组(请参阅链接页面以获得对这些信号的合理描述,并注意BSD/macOS也具有^T和SIGINFO )。但是,如果信号是从其他程序发送的,而不是从控制终端发送的,则取决于该程序是调用killpg还是kill,以及发送什么信号。
有些信号不能被捕捉到。SIGKILL和SIGSTOP就是这种情况。这些信号不应该被发送给威利;它们应该保留到最后的手段。相反,希望另一个程序停止的程序通常应该发送SIGINT、SIGTERM、SIGHUP或(很少) SIGQUIT之一。Go倾向于将SIGQUIT与调试联系在一起(因为POSIX系统上的运行时使^\转储了各种峡谷的堆栈),因此不是一个好的选择。但是,这并不取决于您在这里编写的Go程序,它只能尝试捕捉信号。发送内容的选择取决于发送者。
捕捉信号的“前进之路”是使用一条戈鲁蒂线和一个通道。signal.Notify函数将OS级信号转换为通道上的事件.您不知道(也不可能)的是信号是通过kill还是killpg到达您的进程(尽管如果它来自控制终端交互,POSIX-y内核通过等效的killpg发送它)。如果您希望自己传播该信号,只需使用通知事件来调用进行OS级别kill调用的代码。当使用套餐时,请使用cmd.Process.Signal:注意,这会调用POSIX kill,而不是它的killpg,但是您不会在这里使用killpg,因为我们首先假设的是非进程组信号(基于pgroup的信号大概不需要传播)。
没有完全可移植的方式向POSIX进程组发送信号(这并不奇怪,因为这不能移植到非POSIX系统)。遗憾的是,似乎在Go中也没有直接的Unix或POSIX特定的方法来实现这一点。
在非POSIX系统上,一切都是完全不同的。请参阅套餐前面的讨论。
https://stackoverflow.com/questions/66640005
复制相似问题