122

pid が有効なプロセスに対応しているかどうかを確認する方法はありますか? から以外の別のソースから pid を取得してos.getpid()います。その pid を持つプロセスがマシンに存在しないかどうかを確認する必要があります。

Unix と Windows で利用できるようにする必要があります。PIDが使用されていないかどうかも確認しています。

4

14 に答える 14

181

シグナル 0 を pid に送信すると、pid が実行されていない場合は OSError 例外が発生し、それ以外の場合は何もしません。

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
于 2009-02-20T04:31:14.083 に答える
91

psutilモジュールを見てください:

psutil (python システムおよびプロセス ユーティリティ) は、Python で実行中のプロセスシステム使用率(CPU、メモリ、ディスク、ネットワーク)に関する情報を取得するためのクロスプラットフォーム ライブラリです。[...] 現在、LinuxWindowsOSXFreeBSDSun Solaris 、 32 ビット64ビットの両方のアーキテクチャをサポートしており、Python バージョンは2.6 から 3.4までです (Python 2.4 と 2.5 のユーザーは 2.1.3 バージョンを使用できます)。 . PyPy も機能することが知られています。

pid_exists()指定されたpidを持つプロセスが存在するかどうかを確認するために使用できるという関数があります。

次に例を示します。

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)

参考のため:

于 2013-07-12T19:16:25.830 に答える
66

mluebke コードは 100% 正しいわけではありません。kill() は EPERM (アクセス拒否) を発生させることもできます。この場合、明らかにプロセスが存在することを意味します。これはうまくいくはずです:

(Jason R. Coombs のコメントに従って編集)

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

pywin32、ctypes、または C 拡張モジュールを使用しない限り、Windows でこれを行うことはできません。外部ライブラリに依存しても問題ない場合は、psutilを使用できます。

>>> import psutil
>>> psutil.pid_exists(2353)
True
于 2011-08-04T11:08:51.197 に答える
21

問題のプロセスが test を実行しているユーザーによって所有されている場合にのみ、プロセスに「シグナル 0」を送信することを含む回答が機能します。そうしないと、pid がシステムに存在する場合でも、 OSErrordue to permissionsが発生します。

この制限を回避するには、/proc/<pid>存在するかどうかを確認できます。

import os

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

これは明らかに Linux ベースのシステムにのみ適用されます。

于 2017-01-25T12:33:38.887 に答える
7

実行中のプロセスとその ID の完全なリストを取得する Windows 固有の方法については、こちらを参照してください。それは次のようなものになります

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]

次に、このリストに対して取得した pid を確認できます。パフォーマンス コストについてはわかりません。pid の検証を頻繁に行う場合は、これを確認することをお勧めします。

*NIx の場合は、mluebke のソリューションを使用してください。

于 2009-02-20T07:20:11.260 に答える
4

Giampaolo RodolàのPOSIXに対する答えWindowsに対する私の答えを組み合わせると、次のようになりました。

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
于 2013-07-15T00:24:57.327 に答える
2

Windows では、次の方法で実行できます。

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

まず、このコードでは、pid を指定してプロセスのハンドルを取得しようとしています。ハンドルが有効な場合は、プロセスのハンドルを閉じて True を返します。それ以外の場合は False を返します。OpenProcess のドキュメント: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx

于 2015-01-21T11:19:17.283 に答える
2

これは Linux で機能します。たとえば、banshee が実行されているかどうかを確認したい場合... (banshee は音楽プレーヤーです)

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")
于 2014-05-26T23:00:03.663 に答える
0

次のコードは、Linux と Windows の両方で機能し、外部モジュールに依存しません。

import os
import subprocess
import platform
import re

def pid_alive(pid:int):
    """ Check For whether a pid is alive """


    system = platform.uname().system
    if re.search('Linux', system, re.IGNORECASE):
        try:
            os.kill(pid, 0)
        except OSError:
            return False
        else:
            return True
    elif re.search('Windows', system, re.IGNORECASE):
        out = subprocess.check_output(["tasklist","/fi",f"PID eq {pid}"]).strip()
        # b'INFO: No tasks are running which match the specified criteria.'

        if re.search(b'No tasks', out, re.IGNORECASE):
            return False
        else:
            return True
    else:
        raise RuntimeError(f"unsupported system={system}")

必要に応じて簡単に拡張できます

  1. 他のプラットフォーム
  2. 他の言語
于 2020-08-20T01:56:09.970 に答える
-2

取得する目的に関係なく PID を使用し、エラーを適切に処理することをお勧めします。それ以外の場合は、古典的なレースです (PID が有効であることを確認すると有効である可能性がありますが、すぐに消えます)。

于 2009-02-20T07:39:21.370 に答える