func isGo(pr ps.Process) (path, version string, agent, ok bool, err error) {
	if pr.Pid() == 0 {
		return
	}
	path, err = pr.Path()
	if err != nil {
		return
	}
	var versionInfo goversion.Version
	versionInfo, err = goversion.ReadExe(path)
	if err != nil {
		return
	}
	ok = true
	version = versionInfo.Release
	pidfile, err := internal.PIDFile(pr.Pid())
	if err == nil {
		_, err := os.Stat(pidfile)
		agent = err == nil
	}
	return path, version, agent, ok, nil
}
isGo looks up the runtime.buildVersion symbol
in the process' binary and determines if the process
if a Go process or not. If the process is a Go process,
it reports PID, binary name and full path of the binary.
package goprocess
import (
	"os"
	"sync"
	goversion "rsc.io/goversion/version"
	"github.com/google/gops/internal"
	ps "github.com/keybase/go-ps"
)
type P struct {
	PID          int
	PPID         int
	Exec         string
	Path         string
	BuildVersion string
	Agent        bool
}
func FindAll() []P {
	const concurrencyLimit = 10  
	pss, err := ps.Processes()
	if err != nil {
		return nil
	}
	return findAll(pss, isGo, concurrencyLimit)
}
type isGoFunc func(ps.Process) (path, version string, agent, ok bool, err error)
func findAll(pss []ps.Process, isGo isGoFunc, concurrencyLimit int) []P {
	input := make(chan ps.Process, len(pss))
	output := make(chan P, len(pss))
	for _, ps := range pss {
		input <- ps
	}
	close(input)
	var wg sync.WaitGroup
	wg.Add(concurrencyLimit)  
	for i := 0; i < concurrencyLimit; i++ {
		go func() {
			defer wg.Done()
			for pr := range input {
				path, version, agent, ok, err := isGo(pr)
				if err != nil {
					continue
				}
				if !ok {
					continue
				}
				output <- P{
					PID:          pr.Pid(),
					PPID:         pr.PPid(),
					Exec:         pr.Executable(),
					Path:         path,
					BuildVersion: version,
					Agent:        agent,
				}
			}
		}()
	}
	wg.Wait()      
	close(output)  
	var results []P
	for p := range output {
		results = append(results, p)
	}
	return results
}
func Find(pid int) (p P, ok bool, err error) {
	pr, err := ps.FindProcess(pid)
	if err != nil {
		return P{}, false, err
	}
	path, version, agent, ok, err := isGo(pr)
	if !ok {
		return P{}, false, nil
	}
	return P{
		PID:          pr.Pid(),
		PPID:         pr.PPid(),
		Exec:         pr.Executable(),
		Path:         path,
		BuildVersion: version,
		Agent:        agent,
	}, true, nil
}