¿Hay alguna forma de comprobar si un pid corresponde a un proceso válido? Recibo un pid de una fuente diferente a la de os.getpid()
y necesito verificar si un proceso con ese pid no existe en la máquina.
Necesito que esté disponible en Unix y Windows. También estoy comprobando si el PID NO está en uso.
Respuestas:
El envío de la señal 0 a un pid generará una excepción OSError si el pid no se está ejecutando y no hará nada de lo contrario.
fuente
os.kill(pid, 0)
es el mismoos.kill(pid, signal.CTRL_C_EVENT)
que puede terminar el proceso (o fallar). Obtengo unOSError
dóndeerrno==EINVAL
cuando intento esto en un subproceso.Eche un vistazo al
psutil
módulo:Tiene una función llamada
pid_exists()
que puede usar para verificar si existe un proceso con el pid dado.He aquí un ejemplo:
Para referencia:
fuente
psutil
pid_exists()
es como se implementa en POSIX . Comparar con la respuesta de @Giampaolo Rodolà (autor depsutil
)el código de mluebke no es 100% correcto; kill () también puede generar EPERM (acceso denegado) en cuyo caso eso obviamente significa que existe un proceso. Se supone que esto funciona:
(editado según los comentarios de Jason R. Coombs)
No puede hacer esto en Windows a menos que use pywin32, ctypes o un módulo de extensión C. Si está de acuerdo con depender de una biblioteca externa, puede usar psutil :
fuente
Las respuestas que implican el envío de 'señal 0' al proceso funcionarán solo si el proceso en cuestión es propiedad del usuario que ejecuta la prueba . De lo contrario, obtendrá un
OSError
debido a los permisos , incluso si el pid existe en el sistema.Para evitar esta limitación, puede verificar si
/proc/<pid>
existe:Esto se aplica solo a los sistemas basados en Linux, obviamente.
fuente
PermissionError
significa que pid existe , se obtieneProcessLookupError
si pid no existe.OSError
debido a la denegación de permiso se puede diferenciar de otros - ya sea a través de mirar a errno o por medio de la captura de los más especializadosPermissionError
/ProcessLookupError
excepciones que se derivan deOSError
. Además, solo obtiene el error de permiso si el proceso existe. Por lo tanto, su ejemplo es solo un método alternativo que funciona en Linux y algunos otros Unices, pero no es más completo que llamar correctamenteos.kill(pid, 0)
./proc
procfs solo sale en Linux, ni siquiera en BSD u OSX.En Python 3.3+, puede usar nombres de excepción en lugar de constantes errno. Versión Posix :
fuente
Busque aquí la forma específica de Windows de obtener una lista completa de los procesos en ejecución con sus ID. Seria algo como
A continuación, puede verificar el pid obtenido con esta lista. No tengo idea sobre el costo de rendimiento, por lo que será mejor que verifique esto si va a realizar la verificación de pid con frecuencia.
Para * NIx, simplemente use la solución de mluebke.
fuente
Sobre la base de ntrrgc, he reforzado la versión de Windows para que verifique el código de salida del proceso y verifique los permisos:
fuente
GetExistCodeProcess
requiere los derechos de accesoPROCESS_QUERY_INFORMATION
yPROCESS_QUERY_LIMITED_INFORMATION
.GetExitCodeProcess
recibe un identificador y un puntero y, en esta muestra, recibe unaExitCodeProcess
estructura como segundo parámetro cuando debería ser solo un puntero.Combinando la respuesta de Giampaolo Rodolà para POSIX y la mía para Windows , obtuve esto:
fuente
GetExitCodeProcess
y asegurarte de que incluso tienes acceso.kernel32.OpenProcess
únicamente no es suficiente. Como se señaló aquí , "si el proceso salió recientemente, es posible que todavía exista un pid para el identificador". Sikernel32.OpenProcess
devuelve un valor distinto de cero, aún necesitamoskernel32.GetExitCodeProcess
verificar el código de salida.En Windows, puede hacerlo de esta manera:
En primer lugar, en este código intenta obtener un identificador para el proceso con pid dado. Si el identificador es válido, cierre el identificador para el proceso y devuelva True; de lo contrario, devuelve False. Documentación para OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
fuente
Esto funcionará para Linux, por ejemplo, si desea verificar si banshee se está ejecutando ... (banshee es un reproductor de música)
fuente
os.kill(pid, 0)
o mirar/proc/{pid}
. En lugar de ejecutar una llamada al sistema, su código bifurca a un hijo, ejecuta un shell en ese hijo, el shell interpreta su mini script de shell superfluo, el shell bifurca a otro hijo que ejecuta pgrep y finalmente pgrep itera/proc
. Tu respuesta no responde a la pregunta publicada. El OP pidió un método con un PID. Su método requiere un nombre de proceso.Yo diría que use el PID para cualquier propósito con el que lo obtenga y maneje los errores con elegancia. De lo contrario, es una carrera clásica (el PID puede ser válido cuando verificas que es válido, pero desaparece un instante después)
fuente