process - tool - goose gene ontology
Compruebe si existe un proceso en camino (5)
Si tengo el PID de un proceso, ¿ os.FindProcess es suficiente para probar el proceso existente? Quiero decir, si vuelve err
¿puedo suponer que ha terminado (o muerto)?
Editar:
Acabo de escribir una función de envoltura alrededor de kill -s 0
(prueba de proceso bash de estilo antiguo). Esto funciona sin ningún problema, pero aún estoy contento si hay otras soluciones (hechas con bibliotecas de go) para este problema .:
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
}
En sistemas como Unix (linux, freebsd, etc.) os.FindProcess nunca devolverá un error. No sé lo que sucede en Windows. Esto significa que no sabrá si el PID es correcto hasta que intente utilizar el * os.Process para algo.
Puedes mirar el código aquí .
Esta es la forma tradicional de Unix para ver si un proceso está vivo: envíele una señal de 0 (como lo hizo con su ejemplo de bash).
Desde 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.
Y traducido a 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)
}
}
}
Cuando lo ejecutas, obtienes esto, mostrando que el proceso 123 está muerto, el proceso 1 está vivo pero no es tuyo y el proceso 12606 está vivo y es tuyo.
$ ./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
También puedes usar syscall.Kill
. Esto equivale a menos código.
killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil
Si no se encuentra un pid previamente conocido en el sistema (no estoy seguro de las funciones de ir), significa que el proceso definitivamente ha terminado y se ha unido (en Unix, con la llamada de espera ) también.
Pero por otro lado no es necesariamente cierto. Solo porque existe un pid, no garantiza que sea el mismo proceso que antes. Solo hay 65535 pids válidos en Linux estándar, por ejemplo, y pueden volver a utilizarse cuando hay una envoltura completa. Sin embargo, si revisa con relativa frecuencia, para fines prácticos, no necesita preocuparse por esto (siempre que pid de un nuevo proceso incorrecto que se encuentre no sea una vulnerabilidad de seguridad u otra cosa crítica, que alguien pueda intentar desencadenar intencionalmente para malicioso propósitos).
Enlaces relacionados (y preguntas relacionadas en sus columnas de la derecha):
En Windows, el resultado de os.FindProcess()
parece ser suficiente para verificar si el proceso se está ejecutando.
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
}