Is there a way to check to see if a pid corresponds to a valid process? I\'m getting a pid from a different source other than from os.getpid()
and I need to che
I found that this solution seems to work well in both windows and linux. I used psutil to check.
import psutil
import subprocess
import os
p = subprocess.Popen(['python', self.evaluation_script],stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
pid = p.pid
def __check_process_running__(self,p):
if p is not None:
poll = p.poll()
if poll == None:
return True
return False
def __check_PID_running__(self,pid):
"""
Checks if a pid is still running (UNIX works, windows we'll see)
Inputs:
pid - process id
returns:
True if running, False if not
"""
if (platform.system() == 'Linux'):
try:
os.kill(pid, 0)
if pid<0: # In case code terminates
return False
except OSError:
return False
else:
return True
elif (platform.system() == 'Windows'):
return pid in (p.pid for p in psutil.process_iter())
mluebke code is not 100% correct; kill() can also raise EPERM (access denied) in which case that obviously means a process exists. This is supposed to work:
(edited as per Jason R. Coombs comments)
import errno
import os
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
You can't do this on Windows unless you use pywin32, ctypes or a C extension module. If you're OK with depending from an external lib you can use psutil:
>>> import psutil
>>> psutil.pid_exists(2353)
True
Look here for windows-specific way of getting full list of running processes with their IDs. It would be something like
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]
You can then verify pid you get against this list. I have no idea about performance cost, so you'd better check this if you're going to do pid verification often.
For *NIx, just use mluebke's solution.
I'd say use the PID for whatever purpose you're obtaining it and handle the errors gracefully. Otherwise, it's a classic race (the PID may be valid when you check it's valid, but go away an instant later)
In Windows, you can do it in this way:
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
First of all, in this code you try to get a handle for process with pid given. If the handle is valid, then close the handle for process and return True; otherwise, you return False. Documentation for OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
This will work for Linux, for example if you want to check if banshee is running... (banshee is a music player)
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")