How to check if there exists a process with a given pid in Python?

后端 未结 13 1165
名媛妹妹
名媛妹妹 2020-11-27 11:48

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

相关标签:
13条回答
  • 2020-11-27 11:51

    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())
    
    0 讨论(0)
  • 2020-11-27 11:52

    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
    
    0 讨论(0)
  • 2020-11-27 12:01

    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.

    0 讨论(0)
  • 2020-11-27 12:01

    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)

    0 讨论(0)
  • 2020-11-27 12:03

    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

    0 讨论(0)
  • 2020-11-27 12:03

    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")
    
    0 讨论(0)
提交回复
热议问题