func GetPS(opts ...OpFunc) (pss []PSEntry, err error) {
	op := &EntryOp{}
	op.applyOpts(opts)
	var pids []int64
	switch {
	case op.ProgramMatchFunc == nil && op.PID < 1:
		pids, err = proc.ListPIDs()
		if err != nil {
			return
		}
	case op.PID > 0:
		pids = []int64{op.PID}
	case op.ProgramMatchFunc != nil:
		pids = nil
	default:
	}
	if len(pids) == 0 {
		if pids, err = proc.ListPIDs(); err != nil {
			return
		}
	} else {
		op.ProgramMatchFunc = func(string) bool { return true }
	}
	var topM map[int64]top.Row
	if op.TopStream == nil {
		var topRows []top.Row
		if len(pids) == 1 {
			topRows, err = top.Get(op.TopExecPath, pids[0])
			if err != nil {
				return
			}
		} else {
			topRows, err = top.Get(op.TopExecPath, 0)
			if err != nil {
				return
			}
		}
		topM = make(map[int64]top.Row, len(topRows))
		for _, row := range topRows {
			topM[row.PID] = row
		}
		for _, pid := range pids {
			if _, ok := topM[pid]; !ok {
				topM[pid] = top.Row{PID: pid}
				log.Printf("PID %d is not found at 'top' command output", pid)
			}
		}
	} else {
		topM = op.TopStream.Latest()
	}
	var pmu sync.RWMutex
	var wg sync.WaitGroup
	wg.Add(len(pids))
	limitc := make(chan struct{}, maxConcurrentProcFDLimit)
	for _, pid := range pids {
		go func(pid int64) {
			defer func() {
				<-limitc
				wg.Done()
			}()
			limitc <- struct{}{}
			topRow := topM[pid]
			if !op.ProgramMatchFunc(topRow.COMMAND) {
				return
			}
			pmu.RLock()
			done := op.TopLimit > 0 && len(pss) >= op.TopLimit
			pmu.RUnlock()
			if done {
				return
			}
			ent, err := getPSEntry(pid, topRow)
			if err != nil {
				log.Printf("getPSEntry error %v for PID %d", err, pid)
				return
			}
			pmu.Lock()
			pss = append(pss, ent)
			pmu.Unlock()
		}(pid)
	}
	wg.Wait()
	if op.TopLimit > 0 && len(pss) > op.TopLimit {
		pss = pss[:op.TopLimit:op.TopLimit]
	}
	return
}
GetPS finds all PSEntry by given filter.
package inspect
import (
	"bytes"
	"fmt"
	"log"
	"sync"
	"github.com/gyuho/linux-inspect/proc"
	"github.com/gyuho/linux-inspect/top"
	"github.com/gyuho/dataframe"
	"github.com/olekukonko/tablewriter"
)
type PSEntry struct {
	Program string
	State   string
	PID     int64
	PPID    int64
	CPU    string
	VMRSS  string
	VMSize string
	FD      uint64
	Threads uint64
	VoluntaryCtxtSwitches    uint64
	NonvoluntaryCtxtSwitches uint64
	CPUNum    float64
	VMRSSNum  uint64
	VMSizeNum uint64
}
const maxConcurrentProcFDLimit = 32