最近在写一个应用,下面是用到的代码,网上也有挺多的网友遇到这种问题,下面是我的解决方法,分享一下.
使用方法,想exec.Command的时候使用SetPgid设置进程组,杀的时候使用KillAll杀死全部调用产生的进程
代码实现:
Linux处理方法:
package system import ( "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 system import ( "os" "syscall" "unsafe" ) const ( MAX_PATH = 260 TH32CS_SNAPPROCESS = 0x00000002 ) type ProcessInfo struct { Name string Pid uint32 PPid uint32 } type PROCESSENTRY32 struct { DwSize uint32 CntUsage uint32 Th32ProcessID uint32 Th32DefaultHeapID uintptr Th32ModuleID uint32 CntThreads uint32 Th32ParentProcessID uint32 PcPriClassBase int32 DwFlags uint32 SzExeFile [MAX_PATH]uint16 } type HANDLE uintptr var ( 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 = 0 pids = 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 += 1 length = 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 PROCESSENTRY32 pe32.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 }
有疑问加站长微信联系(非本文作者)