una moneda lanzamiento juego dados dado python process pid

moneda - ¿Cómo verificar si existe un proceso con un pid dado en Python?



juego de dado en python (11)

¿Hay alguna manera de verificar si un pid corresponde a un proceso válido? os.getpid() un pid de una fuente diferente que no sea 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 verificando si el PID NO está en uso.


Al combinar la respuesta de Giampaolo Rodolà para POSIX y la mía para Windows , obtuve esto:

import os if os.name == ''posix'': def pid_exists(pid): """Check whether pid exists in the current process table.""" import errno if pid < 0: return False try: os.kill(pid, 0) except OSError as e: return e.errno == errno.EPERM else: return True else: def pid_exists(pid): import ctypes kernel32 = ctypes.windll.kernel32 SYNCHRONIZE = 0x100000 process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid) if process != 0: kernel32.CloseHandle(process) return True else: return False


Busque here forma específica de Windows de obtener una lista completa de los procesos en ejecución con sus ID. Sería algo así como

from win32com.client import GetObject def get_proclist(): WMI = GetObject(''winmgmts:'') processes = WMI.InstancesOf(''Win32_Process'') return [process.Properties_(''ProcessID'').Value for process in processes]

A continuación, puede verificar pid que obtiene en contra de esta lista. No tengo idea del costo de rendimiento, así que será mejor que lo compruebes si vas a hacer la verificación de pid a menudo.

Para * NIx, solo usa la solución de mluebke.


Echa un vistazo al módulo psutil :

psutil (python system and process utilities) es una biblioteca multiplataforma para recuperar información sobre procesos en ejecución y utilización del sistema (CPU, memoria, discos, red) en Python. [...] Actualmente es compatible con Linux , Windows , OSX , FreeBSD y Sun Solaris , arquitecturas de 32 bits y de 64 bits , con versiones de Python de 2.6 a 3.4 (los usuarios de Python 2.4 y 2.5 pueden usar la versión 2.1.3) . PyPy también se sabe que funciona.

Tiene una función llamada pid_exists() que puede usar para verificar si existe un proceso con el pid dado.

Aquí hay un ejemplo:

import psutil pid = 12345 if psutil.pid_exists(pid): print "a process with pid %d exists" % pid else: print "a process with pid %d does not exist" % pid

Para referencia:


El código 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)

import errno import os import sys def pid_exists(pid): """Check whether pid exists in the current process table. UNIX only. """ if pid < 0: return False if pid == 0: # According to "man 2 kill" PID 0 refers to every process # in the process group of the calling process. # On certain systems 0 is a valid PID but we have no way # to know that in a portable fashion. raise ValueError(''invalid PID 0'') try: os.kill(pid, 0) except OSError as err: if err.errno == errno.ESRCH: # ESRCH == No such process return False elif err.errno == errno.EPERM: # EPERM clearly means there''s a process to deny access to return True else: # According to "man 2 kill" possible error values are # (EINVAL, EPERM, ESRCH) raise else: return True

No puede hacer esto en Windows a menos que use pywin32, ctypes o un módulo de extensión C. Si estás de acuerdo con depender de una lib externa, puedes usar psutil :

>>> import psutil >>> psutil.pid_exists(2353) True


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.

import os def check_pid(pid): """ Check For the existence of a unix pid. """ try: os.kill(pid, 0) except OSError: return False else: return True


En Python 3.3+, puede usar nombres de excepción en lugar de constantes de errno. Versión de Posix :

import os def pid_exists(pid): if pid < 0: return False #NOTE: pid == 0 returns True try: os.kill(pid, 0) except ProcessLookupError: # errno.ESRCH return False # No such process except PermissionError: # errno.EPERM return True # Operation not permitted (i.e., process exists) else: return True # no error, we can send a signal to the process


En Windows, puede hacerlo de esta manera:

import ctypes PROCESS_QUERY_INFROMATION = 0x1000 def checkPid(pid): processHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFROMATION, 0,pid) if processHandle == 0: return False else: ctypes.windll.kernel32.CloseHandle(processHandle) return True

En primer lugar, en este código, intenta obtener un control para el proceso con pid dado. Si el identificador es válido, cierre el identificador del 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


Esto funcionará para Linux, por ejemplo, si quieres comprobar si se está ejecutando banshee ... (banshee es un reproductor de música)

import subprocess def running_process(process): "check if process is running. < process > is the name of the process." proc = subprocess.Popen(["if pgrep " + process + " >/dev/null 2>&1; then echo ''True''; else echo ''False''; fi"], stdout=subprocess.PIPE, shell=True) (Process_Existance, err) = proc.communicate() return Process_Existance # use the function print running_process("banshee")


Las respuestas que envían el envío de la "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 omitir esta limitación, puede verificar si existe /proc/<pid> :

import os def is_running(pid): if os.path.isdir(''/proc/{}''.format(pid)): return True return False


Sobre la base de ntrrgc''s he reforzado la versión de Windows para que compruebe el código de salida del proceso y compruebe los permisos:

def pid_exists(pid): """Check whether pid exists in the current process table.""" if os.name == ''posix'': import errno if pid < 0: return False try: os.kill(pid, 0) except OSError as e: return e.errno == errno.EPERM else: return True else: import ctypes kernel32 = ctypes.windll.kernel32 HANDLE = ctypes.c_void_p DWORD = ctypes.c_ulong LPDWORD = ctypes.POINTER(DWORD) class ExitCodeProcess(ctypes.Structure): _fields_ = [ (''hProcess'', HANDLE), (''lpExitCode'', LPDWORD)] SYNCHRONIZE = 0x100000 process = kernel32.OpenProcess(SYNCHRONIZE, 0, pid) if not process: return False ec = ExitCodeProcess() out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec)) if not out: err = kernel32.GetLastError() if kernel32.GetLastError() == 5: # Access is denied. logging.warning("Access is denied to get pid info.") kernel32.CloseHandle(process) return False elif bool(ec.lpExitCode): # print ec.lpExitCode.contents # There is an exist code, it quit kernel32.CloseHandle(process) return False # No exit code, it''s running. kernel32.CloseHandle(process) return True


Yo diría que use el PID para cualquier propósito que lo esté obteniendo y maneje los errores con gracia. De lo contrario, es una carrera clásica (el PID puede ser válido cuando se comprueba que es válido, pero se va un instante más tarde)