场景:
程序依赖另外一个程序,并开放个端口。遂启动时先 process:=exec.Command() process.Start().
问题来了,每次 ctrl+c 退出时,这个子进程就孤儿了。
所以想:
监听个 SIGINT 信号,信号来时直接 p.Kill()。测试,好使。
然后就封装了一下。
#伪代码
#proj/intenal/process/process.go
func(p *process) Go() {
p.cmd.Start()
chan ...signal
os.Notify....
go func <-chan; p.cmd.Kill()
}
新问题:ctrl+c 后。子进程退出了,主进程还活着。
不想 在项目里显式的 exec.Command(....一堆。
既然连 exec.Command 都没有了。也就不想在最外层监听信号再传到自己封的 process 里。
那么问题来了:怎么能在内部包的里面使用信号还不影响信号本身对程序的影响呢?
其实就是想:
#main
func main() {
internal.process.New().Go() # 一行,没有信号,没有需要关注的 ctx
http.ServerStart()
https.ServerStart()
rpc.ServerStart()
# 整个 main 就几行就行了。
}
1
ch2 2022-08-19 17:47:07 +08:00 1
server 为什么要 ctrl+c 终止?
|
2
codehz 2022-08-19 17:58:00 +08:00 via iPhone
可以试试
flag := unix.SIGHUP if err := unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(flag), 0, 0, 0); err != nil { return } |
3
reter 2022-08-19 17:59:01 +08:00
看了文档,当你监听了 SIGINT 信号,就相当于覆盖了 go 对 SIGINT 的默认行为(退出程序)
简单方法:让 main 函数也监听 SIGINT 信号。 |
4
dzdh OP go1.19 的 SysProcAttr 新增一个 Pdeathsig
在 start 前 cmd.Process.SysProcAttr=&syscall.SysProcAttr{ Pdeathsig: syscall.SIGTERM} 即可。 不知道有啥坑。https://go.dev/issue/27505. |
6
Nitroethane 2022-08-19 18:33:02 +08:00
用 `exec.CommandContext()` 方法,你 ctrl-c 的时候 cancel parent context ,起的这个子进程会被自动 kill 掉。
|
7
glasslion 2022-08-19 20:16:16 +08:00
|
8
monkeyNik 2022-08-19 20:27:23 +08:00 via iPhone
为啥不使用 socketpair ?进程退出,另一端套接字直接 read 返回 0
|
9
a632079 2022-08-20 22:37:24 +08:00
按你的需求,如果我没理解错的话,直接在监听 SIGINT 的自定义方法末尾补个 os.Exit 就好了吧
|