You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中主进程终止时如何终止子进程

在Go中确保主进程终止时终止子进程

下面是几种可行的方案,覆盖不同场景与平台:

1. 利用进程组(Unix-like系统适用)

在Unix类系统中,将子进程设置为新进程组的组长后,当主进程意外终止时,系统会向整个进程组发送SIGHUP信号,子进程默认会响应此信号退出。

实现时只需在启动子进程时配置SysProcAttr:

package main

import (
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("sleep", "60")
	// 让子进程成为新进程组的组长
	cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

	if err := cmd.Start(); err != nil {
		panic(err)
	}

	cmd.Wait()
}

如果子进程刻意忽略SIGHUP,则需要额外处理,但绝大多数程序都会默认响应该信号。

2. 监听退出信号主动终止子进程

这种方法适用于主进程能捕获到退出信号的场景(比如SIGINT、SIGTERM),但如果主进程被强制终止(如kill -9),该方法无效——因为此时主进程没有机会执行任何清理代码。

实现思路是启动goroutine监听信号,收到信号后调用子进程的Kill()方法:

package main

import (
	"os"
	"os/exec"
	"os/signal"
	"syscall"
)

func main() {
	cmd := exec.Command("sleep", "60")
	if err := cmd.Start(); err != nil {
		panic(err)
	}

	sigChan := make(chan os.Signal, 1)
	// 监听常见的退出信号
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)

	go func() {
		<-sigChan
		// 收到信号后终止子进程
		_ = cmd.Kill()
	}()

	cmd.Wait()
}

3. 跨平台绑定子进程生命周期

如果需要同时支持Windows和Unix-like系统,可以根据系统差异配置不同的SysProcAttr参数:

package main

import (
	"os"
	"os/exec"
	"syscall"
)

func main() {
	cmd := exec.Command("sleep", "60")
	var sysProcAttr *syscall.SysProcAttr

	if os.PathSeparator == '\\' {
		// Windows系统:创建新进程组
		sysProcAttr = &syscall.SysProcAttr{CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP}
	} else {
		// Unix-like系统:设置子进程为新进程组组长
		sysProcAttr = &syscall.SysProcAttr{Setpgid: true}
	}
	cmd.SysProcAttr = sysProcAttr

	if err := cmd.Start(); err != nil {
		panic(err)
	}

	cmd.Wait()
}

另外可以尝试用runtime.SetFinalizer作为补充,但该方法依赖Go的垃圾回收时机,可靠性不足,不建议作为核心方案。

关键注意事项

  • 只有进程组方案能应对kill -9这类强制终止主进程的场景,因为此时主进程无法执行任何代码,只能依赖系统层面的信号传递。
  • 若子进程是守护进程(会主动脱离进程组),则需要额外逻辑,比如记录子进程PID,在主进程启动时清理残留的旧进程。

内容的提问来源于stack exchange,提问作者체라치</think_never_used_51bce0c785ca2f68081bfa7d91973934>

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:55:09