最近在写一个应用,下面是用到的代码,网上也有挺多的网友遇到这种问题,下面是我的解决方法,分享一下.

使用方法,想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

}