這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近在寫一個應用,下面是用到的代碼,網上也有挺多的網友遇到這種問題,下面是我的解決方案,分享一下.
使用方法,想exec.Command的時候使用SetPgid設定進程組,殺的時候使用KillAll殺死全部調用產生的進程
代碼實現:
Linux處理方法:
package systemimport ("syscall")func SetPgid(pid, pgid int) error {return syscall.Setpgid(pid, pgid)}func GetPPids(pid int) ([]int, error) {return []int{}, nil}func Kill(pids []uint32) {for _, pid := range pids {syscall.Kill(int(pid), syscall.SIGKILL)}}func KillAll(pid int) error {return syscall.Kill(pid-(pid*2), syscall.SIGKILL)}
Windows處理方法:
package systemimport ("os""syscall""unsafe")const (MAX_PATH = 260TH32CS_SNAPPROCESS = 0x00000002)type ProcessInfo struct {Name stringPid uint32PPid uint32}type PROCESSENTRY32 struct {DwSize uint32CntUsage uint32Th32ProcessID uint32Th32DefaultHeapID uintptrTh32ModuleID uint32CntThreads uint32Th32ParentProcessID uint32PcPriClassBase int32DwFlags uint32SzExeFile [MAX_PATH]uint16}type HANDLE uintptrvar (modkernel32 = syscall.NewLazyDLL("kernel32.dll")procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")procProcess32First = modkernel32.NewProc("Process32FirstW")procProcess32Next = modkernel32.NewProc("Process32NextW")procCloseHandle = modkernel32.NewProc("CloseHandle"))func SetPgid(pid, pgid int) error {return nil}func KillAll(pid int) error {pids := Getppids(uint32(pid))Kill(pids)return nil}func Kill(pids []uint32) {for _, pid := range pids {pro, err := os.FindProcess(int(pid))if err != nil {continue}pro.Kill()}}func Getppids(pid uint32) []uint32 {infos, err := GetProcs()if err != nil {return []uint32{pid}}var pids []uint32 = make([]uint32, 0, len(infos))var index int = 0pids = append(pids, pid)var length int = len(pids)for index < length {for _, info := range infos {if info.PPid == pids[index] {pids = append(pids, info.Pid)}}index += 1length = len(pids)}return pids}func GetProcs() (procs []ProcessInfo, err error) {snap := createToolhelp32Snapshot(TH32CS_SNAPPROCESS, uint32(0))if snap == 0 {err = syscall.GetLastError()return}defer closeHandle(snap)var pe32 PROCESSENTRY32pe32.DwSize = uint32(unsafe.Sizeof(pe32))if process32First(snap, &pe32) == false {err = syscall.GetLastError()return}procs = append(procs, ProcessInfo{syscall.UTF16ToString(pe32.SzExeFile[:260]), pe32.Th32ProcessID, pe32.Th32ParentProcessID})for process32Next(snap, &pe32) {procs = append(procs, ProcessInfo{syscall.UTF16ToString(pe32.SzExeFile[:260]), pe32.Th32ProcessID, pe32.Th32ParentProcessID})}return}func createToolhelp32Snapshot(flags, processId uint32) HANDLE {ret, _, _ := procCreateToolhelp32Snapshot.Call(uintptr(flags),uintptr(processId))if ret <= 0 {return HANDLE(0)}return HANDLE(ret)}func process32First(snapshot HANDLE, pe *PROCESSENTRY32) bool {ret, _, _ := procProcess32First.Call(uintptr(snapshot),uintptr(unsafe.Pointer(pe)))return ret != 0}func process32Next(snapshot HANDLE, pe *PROCESSENTRY32) bool {ret, _, _ := procProcess32Next.Call(uintptr(snapshot),uintptr(unsafe.Pointer(pe)))return ret != 0}func closeHandle(object HANDLE) bool {ret, _, _ := procCloseHandle.Call(uintptr(object))return ret != 0}