【问题标题】:Cross-platform way to get PIDs by process name in python在 python 中通过进程名称获取 PID 的跨平台方法
【发布时间】:2010-10-07 17:32:18
【问题描述】:

主机上正在运行多个同名进程。使用 pythonjython 按名称获取这些进程的 PID 的跨平台方法是什么?

  1. 我想要 pidof 之类的东西,但在 python 中。 (反正我没有pidof。)
  2. 我无法解析 /proc,因为它可能不可用(在 HP-UX 上)。
  3. 我不想运行os.popen('ps') 并解析输出,因为我认为它很难看(不同操作系统中的字段顺序可能不同)。
  4. 目标平台是 Solaris、HP-UX 等。

【问题讨论】:

    标签: python cross-platform jython hp-ux


    【解决方案1】:

    您可以使用适用于 Windows 和 UNIX 的 psutil (https://github.com/giampaolo/psutil):

    import psutil
    
    PROCNAME = "python.exe"
    
    for proc in psutil.process_iter():
        if proc.name() == PROCNAME:
            print(proc)
    

    在我的机器上打印:

    <psutil.Process(pid=3881, name='python.exe') at 140192133873040>
    

    编辑 2017-04-27 - 这是一个更高级的实用程序函数,它根据进程的 name()、cmdline() 和 exe() 检查名称:

    import os
    import psutil
    
    def find_procs_by_name(name):
        "Return a list of processes matching 'name'."
        assert name, name
        ls = []
        for p in psutil.process_iter():
            name_, exe, cmdline = "", "", []
            try:
                name_ = p.name()
                cmdline = p.cmdline()
                exe = p.exe()
            except (psutil.AccessDenied, psutil.ZombieProcess):
                pass
            except psutil.NoSuchProcess:
                continue
            if name == name_ or cmdline[0] == name or os.path.basename(exe) == name:
                ls.append(p)
        return ls
    

    【讨论】:

    • 不幸的是,OS X 不允许您访问进程的许多属性(名称、exe、cmdline),即使您只尝试访问那些由您创建的进程。除非您使用 sudo 运行解释器/脚本,否则就是这样。
    • 是的,这是 OSX 的一个限制(它是唯一一个这样的平台)。除了使用 sudo/setuid 之外,您无能为力。
    • 更新 - 现在已针对不同的方法修复此问题,请参阅:code.google.com/p/psutil/issues/detail?id=297
    • 在我的环境中,.name 是一种方法,而不是一种属性。
    • 那么这将如何从多个 python 进程中识别我的进程?
    【解决方案2】:

    没有单一的跨平台 API,您必须检查操作系统。对于基于 posix 的使用 /proc。对于 Windows,使用以下代码获取具有对应进程名称的所有 pid 的列表

    from win32com.client import GetObject
    WMI = GetObject('winmgmts:')
    processes = WMI.InstancesOf('Win32_Process')
    process_list = [(p.Properties_("ProcessID").Value, p.Properties_("Name").Value) for p in processes]
    

    然后您可以轻松过滤掉您需要的流程。 有关 Win32_Process 可用属性的更多信息,请查看Win32_Process Class

    【讨论】:

    【解决方案3】:
    import psutil
    
    process = filter(lambda p: p.name() == "YourProcess.exe", psutil.process_iter())
    for i in process:
      print i.name,i.pid
    

    给出“YourProcess.exe”的所有pid

    【讨论】:

    • 我不持有任何股份;我经常听到人们抱怨说列表理解是总是过滤列表的最佳方法,因为它更快。例如process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"].
    【解决方案4】:

    关于ThorSummoner's comment的注释

    process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"].
    

    我已经在 Debian 上使用 Python 3 进行了尝试,我认为它必须是 proc.name() 而不是 proc.name

    【讨论】:

      【解决方案5】:

      首先,Windows(它的所有化身)是一个非标准操作系统。

      Linux(以及大多数专有的 unixen)是符合 POSIX 的标准操作系统。

      C 库反映了这种二分法。 Python 反映了 C 库。

      没有“跨平台”的方式来做到这一点。您必须使用 ctypes 破解特定版本的 Windows(XP 或 Vista)

      【讨论】:

        【解决方案6】:

        我认为如果不使用 /proc 或命令行实用程序,您将无法找到纯粹基于 python 的可移植解决方案,至少在 python 本身中不会。解析 os.system 并不难看——有人必须处理多个平台,无论是你还是其他人。老实说,为您感兴趣的操作系统实现它应该相当容易。

        【讨论】:

          【解决方案7】:

          恐怕没有。进程由 pid 而不是名称唯一标识。如果您确实必须按名称查找 pid,那么您将使用您建议的方法,但它不是可移植的,并且可能无法在所有情况下工作。

          如果您只需要查找某个应用程序的 pid 并且您可以控制此应用程序,那么我建议您更改此应用程序以将其 pid 存储在您的脚本可以找到的某个位置的文件中。

          【讨论】:

            【解决方案8】:

            对于jython,如果使用Java 5,那么你可以得到Java进程ID如下:

            从 java.lang.management 导入 *
            pid = ManagementFactory.getRuntimeMXBean().getName()

            【讨论】:

            • 可行,但我想获取另一个进程的 PID(如 pidof 做但不使用 pidof)
            【解决方案9】:

            只需使用:

            def get_process_by_name(name):
                import re, psutil
                ls = list()
                for p in psutil.process_iter():
                    if hasattr(p, 'name'):
                        if re.match(".*" + name + ".*", p.name()):
                            ls.append(p)
                return ls
            

            返回进程对象

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-09-15
              • 2011-05-10
              • 2014-12-28
              • 1970-01-01
              • 1970-01-01
              • 2021-08-19
              相关资源
              最近更新 更多