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

dev
truthhun 1 year ago
parent d60572d070
commit 35b61eb2e4

@ -16,8 +16,12 @@ limitations under the License.
package cmd
import (
"fmt"
"moredoc/service"
"moredoc/util"
"moredoc/util/command"
"os"
"os/signal"
"github.com/spf13/cobra"
)
@ -31,6 +35,20 @@ var serveCmd = &cobra.Command{
util.Version = Version
util.Hash = GitHash
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)
},
}

@ -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 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
distributed under the License is distributed on an "AS IS" BASIS,
@ -15,8 +15,11 @@ limitations under the License.
*/
package main
import "moredoc/cmd"
import (
"moredoc/cmd"
)
func main() {
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
}
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() {
if cmd.Process != nil && cmd.Process.Pid != 0 {
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
}
// 当主程序退出时从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
}
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() {
if cmd.Process != nil && cmd.Process.Pid != 0 {
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
}
// 当主程序退出时从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
}
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() {
if cmd.Process != nil && cmd.Process.Pid != 0 {
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
}
// 当主程序退出时从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