主程序退出时,关闭子进程

dev
truthhun 1 year ago
parent d60572d070
commit 35b61eb2e4

@ -16,8 +16,12 @@ limitations under the License.
package cmd package cmd
import ( import (
"fmt"
"moredoc/service" "moredoc/service"
"moredoc/util" "moredoc/util"
"moredoc/util/command"
"os"
"os/signal"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -31,6 +35,20 @@ var serveCmd = &cobra.Command{
util.Version = Version util.Version = Version
util.Hash = GitHash util.Hash = GitHash
util.BuildAt = BuildAt util.BuildAt = BuildAt
c := make(chan os.Signal, 1)
signal.Notify(c)
go func() {
//阻塞直至有信号传入
s := <-c
// 收到退出信号,关闭子进程
fmt.Println("get signal", s)
fmt.Println("close child process...")
command.CloseChildProccess()
fmt.Println("close child process done.")
fmt.Println("exit.")
os.Exit(0)
}()
service.Run(cfg, logger) service.Run(cfg, logger)
}, },
} }

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -15,8 +15,11 @@ limitations under the License.
*/ */
package main package main
import "moredoc/cmd" import (
"moredoc/cmd"
)
func main() { func main() {
cmd.Execute() cmd.Execute()
} }

@ -0,0 +1,8 @@
package command
import (
"sync"
)
// pidMap 用于存储所有的子进程pid以便在主程序退出时kill掉所有的相关子进程
var pidMap sync.Map

@ -32,6 +32,17 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
return return
} }
pid := 0
if cmd.Process != nil && cmd.Process.Pid != 0 {
pid = cmd.Process.Pid
pidMap.Store(pid, pid)
}
defer func() {
if pid != 0 {
pidMap.Delete(pid)
}
}()
time.AfterFunc(expire, func() { time.AfterFunc(expire, func() {
if cmd.Process != nil && cmd.Process.Pid != 0 { if cmd.Process != nil && cmd.Process.Pid != 0 {
errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes()))) errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes())))
@ -51,3 +62,14 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
} }
return return
} }
// 当主程序退出时从pidMap中获取所有的pid然后kill掉
func CloseChildProccess() {
pidMap.Range(func(key, value interface{}) bool {
if pid, ok := value.(int); ok {
fmt.Println("kill pid:", pid)
syscall.Kill(-pid, syscall.SIGKILL)
}
return true
})
}

@ -32,6 +32,17 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
return return
} }
pid := 0
if cmd.Process != nil && cmd.Process.Pid != 0 {
pid = cmd.Process.Pid
pidMap.Store(pid, pid)
}
defer func() {
if pid != 0 {
pidMap.Delete(pid)
}
}()
time.AfterFunc(expire, func() { time.AfterFunc(expire, func() {
if cmd.Process != nil && cmd.Process.Pid != 0 { if cmd.Process != nil && cmd.Process.Pid != 0 {
errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes()))) errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes())))
@ -51,3 +62,14 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
} }
return return
} }
// 当主程序退出时从pidMap中获取所有的pid然后kill掉
func CloseChildProccess() {
pidMap.Range(func(key, value interface{}) bool {
if pid, ok := value.(int); ok {
fmt.Println("kill pid:", pid)
syscall.Kill(-pid, syscall.SIGKILL)
}
return true
})
}

@ -35,6 +35,17 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
return return
} }
pid := 0
if cmd.Process != nil && cmd.Process.Pid != 0 {
pid = cmd.Process.Pid
pidMap.Store(pid, pid)
}
defer func() {
if pid != 0 {
pidMap.Delete(pid)
}
}()
time.AfterFunc(expire, func() { time.AfterFunc(expire, func() {
if cmd.Process != nil && cmd.Process.Pid != 0 { if cmd.Process != nil && cmd.Process.Pid != 0 {
errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes()))) errs = append(errs, fmt.Sprintf("execute timeout: %d min.", int(expire.Minutes())))
@ -57,3 +68,17 @@ func ExecCommand(name string, args []string, timeout ...time.Duration) (out stri
} }
return return
} }
// 当主程序退出时从pidMap中获取所有的pid然后kill掉
func CloseChildProccess() {
pidMap.Range(func(key, value interface{}) bool {
if pid, ok := value.(int); ok {
fmt.Println("kill pid:", pid)
if proc, err := os.FindProcess(pid); err == nil {
proc.Kill()
proc.Release()
}
}
return true
})
}

Loading…
Cancel
Save