如果我有一个进程的PID,那么os.FindProcess是否足以测试现有的进程?我的意思是,如果它返回err
,我可以假设它已被终止(或被杀死)吗?
编辑:
我刚刚在kill -s 0
(旧式bash进程测试)周围编写了一个包装函数。这没有任何问题,但是如果有其他解决方案(使用go库完成)我仍然很高兴。:
func checkPid(pid int) bool {
out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput()
if err != nil {
log.Println(err)
}
if string(out) == "" {
return true // pid exist
}
return false
}
答案 0 :(得分:29)
以下是传统的unix方法,可以查看进程是否处于活动状态 - 向其发送0信号(就像您使用bash示例一样)。
来自kill(2)
:
If sig is 0, then no signal is sent, but error checking is still per‐ formed; this can be used to check for the existence of a process ID or process group ID.
并翻译成Go
package main
import (
"fmt"
"log"
"os"
"strconv"
"syscall"
)
func main() {
for _, p := range os.Args[1:] {
pid, err := strconv.ParseInt(p, 10, 64)
if err != nil {
log.Fatal(err)
}
process, err := os.FindProcess(int(pid))
if err != nil {
fmt.Printf("Failed to find process: %s\n", err)
} else {
err := process.Signal(syscall.Signal(0))
fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err)
}
}
}
当你运行它时,你得到这个,表明进程123已经死了,进程1仍然存在,但不归你所有,进程12606是活着的并由你拥有。
$ ./kill 1 $$ 123
process.Signal on pid 1 returned: operation not permitted
process.Signal on pid 12606 returned: <nil>
process.Signal on pid 123 returned: no such process
答案 1 :(得分:5)
在类似unix的系统(linux,freebsd等)上,os.FindProcess永远不会返回错误。我不知道Windows上会发生什么。这意味着在尝试使用* os.Process之前,你不会知道PID是否正确。
您可以查看代码here。
答案 2 :(得分:3)
您也可以使用syscall.Kill
。它相当于更少的代码。
killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil
答案 3 :(得分:2)
如果在系统中找不到以前已知的pid(不确定go函数),则表示进程已经终止并已加入(在Unix上,wait call)。
但其他方式并不一定如此。仅仅因为存在pid,它并不保证它与以前的过程相同。例如,标准Linux中只有65535个有效的pid,并且当存在环绕时它们可以被重用。但是,如果您经常合理地检查,出于实际目的,您不需要关心这一点(只要找到错误的新进程的pid不是安全漏洞或其他关键的东西,有人可能会试图故意触发恶意目的)。
相关链接(及其右栏中的相关问题):
答案 4 :(得分:0)
在Windows上检查os.FindProcess()
的结果似乎足以检查进程是否正在运行。
func isProcessRunning(pid int) bool {
_, err = os.FindProcess(pid)
if err != nil {
return false
}
if runtime.GOOS == "windows" {
return true
}
return false // further checking for other systems then Windows is not supported here
}
答案 5 :(得分:0)
到目前为止,所有答案都是不完整的实现。参见https://github.com/shirou/gopsutil/blob/c141152a7b8f59b63e060fa8450f5cd5e7196dfb/process/process_posix.go#L73了解更完整的实现(内联复制)
func PidExists(pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
}
proc, err := os.FindProcess(int(pid))
if err != nil {
return false, err
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
}
if err.Error() == "os: process already finished" {
return false, nil
}
errno, ok := err.(syscall.Errno)
if !ok {
return false, err
}
switch errno {
case syscall.ESRCH:
return false, nil
case syscall.EPERM:
return true, nil
}
return false, err
}
答案 6 :(得分:0)
搜索几个小时后,以下是确定进程是否正在Windows上运行的正确答案:
func CheckProcessLife(pid int){
cmd,_ := exec.Command("tasklist","/FI", "PID eq " + strconv.Itoa(pid)).Output()
output := string(cmd[:])
splitOutp := strings.Split(output, " ")
if !(splitOutp[1] == "no") {
time.Sleep(500 * time.Millisecond)
fmt.Println("Process is running...")
CheckProcessLife(pid)
}else{
fmt.Println("Process is no longer running.")
}
}
您可以检查进程是使用其PID还是直接使用其名称运行,只需更改此行:
cmd,_ := exec.Command("tasklist","/FI", "IMAGENAME eq yourprocessname.exe").Output()
答案 7 :(得分:0)
这是一种如何检查进程是否存在/在 Windows 上使用 Golang 运行的方法。
我们执行命令:
TASKLIST /V /NH /FI "PID eq 23232"
哪个可以返回:
INFO: No tasks are running which match the specified criteria.
或者如果找到:
Image Name PID Session Name Session# Mem Usage Status User Name CPU Time Window Title
========================= ======== ================ =========== ============ =============== ================================================== ============ ========================================================================
chrome.exe 23232 Console 1 42,472 K Unknown THANOS\MARVEL 0:00:00 N/A
这是一个利用这些信息的函数。
func isProcessRunning(pid int) bool {
cmd := exec.Command("TASKLIST", "/FI", fmt.Sprintf("PID eq %d", pid))
result, err := cmd.Output()
if err != nil {
return false
}
return !bytes.Contains(result, []byte("No tasks are running"))
}
最好的一点是你也可以通过其他参数找到进程:
ImageName eq, ne Image Name String
PID eq, ne, gt, lt, ge, le Process ID, A Positive integer.
Session eq, ne, gt, lt, ge, le Any valid session number.
SessionName eq, ne String
Status eq, ne RUNNING | NOT RESPONDING | UNKNOWN
CPUTime eq, ne, gt, lt, ge, le Time hh:mm:ss
MemUsage eq, ne, gt, lt, ge, le Memory usage in KB, specify a valid integer.
Username eq, ne User name ([Domain\]User).
Services eq, ne Service Name String
Windowtitle eq, ne Window Title String
Modules eq, ne DLL Name String