func KillServer(pid int, opts ...string) (err error) {
	return SendSignal(pid, syscall.SIGKILL, opts...)
}
KillServer kills server with given pid, it acts like shell command "kill -9",
it will also remove pid file if pid file path is specified as opts
package linux
import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"github.com/romberli/log"
	"github.com/romberli/go-util/constant"
	"github.com/shirou/gopsutil/v3/process"
)
func IsRunningWithPid(pid int) (bool, error) {
	_, err := process.NewProcess(int32(pid))
	if err != nil {
		if err == process.ErrorProcessNotRunning {
			return false, nil
		}
		return false, err
	}
	return true, nil
}
func SavePid(pid int, pidFile string, fileMode os.FileMode) error {
	return ioutil.WriteFile(pidFile, []byte(fmt.Sprintf("%d", pid)), fileMode)
}
func IsRunningWithPidFile(pidFile string) (bool, error) {
	exists, err := PathExists(pidFile)
	if err != nil {
		return false, err
	}
	if !exists {
		return false, errors.New(fmt.Sprintf("pid file does not exists. pid file: %s", pidFile))
	}
	pidBytes, err := ioutil.ReadFile(pidFile)
	if err != nil {
		return false, err
	}
	pid, err := strconv.Atoi(string(pidBytes))
	if err != nil {
		return false, err
	}
	return IsRunningWithPid(pid)
}
func GetPidFromPidFile(pidFile string) (int, error) {
	var (
		err      error
		pidBytes []byte
		pidStr   string
		pid      int
	)
	pidBytes, err = ioutil.ReadFile(pidFile)
	if err != nil {
		return constant.ZeroInt, err
	}
	pidStr = strings.TrimSpace(string(pidBytes))
	pid, err = strconv.Atoi(pidStr)
	if err != nil {
		return constant.ZeroInt, err
	}
	return pid, nil
}
func RemovePidFile(pidFile string) error {
	var (
		err           error
		pidFileExists bool
	)
	pidFileExists, err = PathExists(pidFile)
	if err != nil {
		return err
	}
	if !pidFileExists {
		return errors.New(fmt.Sprintf("pid file does not exists, please have a check. pid file: %s", pidFile))
	}
	return os.Remove(pidFile)
}
func SendSignal(pid int, sig syscall.Signal, opts ...string) (err error) {
	p, err := os.FindProcess(pid)
	if err != nil {
		return err
	}
	err = p.Signal(sig)
	if err != nil {
		return err
	}
	if len(opts) > constant.ZeroInt {
		pidFile := opts[constant.ZeroInt]
		return RemovePidFile(pidFile)
	}
	return nil
}