【问题标题】:Change process priority in Python, cross-platform在 Python 中更改进程优先级,跨平台
【发布时间】:2025-12-06 02:40:01
【问题描述】:

我有一个执行耗时计算的 Python 程序。由于它使用高 CPU,并且我希望我的系统保持响应,我希望程序将其优先级更改为低于正常值。

我发现了这个: Set Process Priority In Windows - ActiveState

但我正在寻找一个跨平台的解决方案。

【问题讨论】:

    标签: python


    【解决方案1】:

    这是我用来将我的进程设置为低于正常优先级的解决方案:

    lowpriority.py

    def lowpriority():
        """ Set the priority of the process to below-normal."""
    
        import sys
        try:
            sys.getwindowsversion()
        except AttributeError:
            isWindows = False
        else:
            isWindows = True
    
        if isWindows:
            # Based on:
            #   "Recipe 496767: Set Process Priority In Windows" on ActiveState
            #   http://code.activestate.com/recipes/496767/
            import win32api,win32process,win32con
    
            pid = win32api.GetCurrentProcessId()
            handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
            win32process.SetPriorityClass(handle, win32process.BELOW_NORMAL_PRIORITY_CLASS)
        else:
            import os
    
            os.nice(1)
    

    在 Windows 和 Linux 上的 Python 2.6 上测试。

    【讨论】:

    • 不错的解决方案,但为什么你调用 sys.getwindowversion() 而不是检查 sys.platform?
    • 我只想可靠地知道我是否在 Windows 上运行。 sys.platform does have documented return values 但我不确定它是否值得信赖——它真的会在 64 位 Windows 上返回 'win32' 吗? (信不信由你,我还没有 64 位 Windows 可以试用!我想我现在应该可以工作了)
    • 在 Win7 64bit(使用 Python 64bit)上试过:sys.platform 确实返回 'win32'
    • @CraigMcQueen;在 2008 R2 服务器上确认 -- sys.platform 返回“win32”
    • 为什么不只是win32process.SetPriorityClass(win32api.GetCurrentProcess(), win32process.HIGH_PRIORITY_CLASS)
    【解决方案2】:

    您可以使用psutil 模块。

    在 POSIX 平台上:

    >>> import psutil, os
    >>> p = psutil.Process(os.getpid())
    >>> p.nice()
    0
    >>> p.nice(10)  # set
    >>> p.nice()
    10
    

    在 Windows 上:

    >>> p.nice(psutil.HIGH_PRIORITY_CLASS)
    

    【讨论】:

    • 感谢您的链接。遗憾的是,两个平台上的 API 不同(10psutil.HIGH_PRIORITY_CLASS)。 “跨平台”是指“所有平台上的相同 API”。
    • 遗憾的是 Python 社区在可移植性方面做到了这一点。他们对“便携”的定义是“我们将实现操作系统让我们轻松做的任何事情”。为什么 select() 不能在 Windows 中的管道上工作?这是可行的,但操作系统不会为你做这件事,所以它没有实现。 Python 是可移植的,只要你不需要任何库,实际上是永远不需要的。
    • 某些东西 本质上 是不可移植的,独立于语言,Python 作为一门语言也不例外(基本上是因为它不能)。现在,我很想听听您对如何始终如一地重新设计 psutil 的出色功能以便跨 POSIX 和 Windows 平台兼容的意见。如果你的提议是合理的,我会改变当前的 API 并感谢你的贡献,否则我会断定你只是在拖钓,因为我在你的消息中看不到任何建设性的建议。
    • 进程优先级不是“天生不可移植的”;只是没有人费心去抽象出 Linux、MacOS 和 Windows 优先系统的适当子集。让 Python 中的子进程系统提供对进程优先级的更好控制并不难——您只需实现所有操作系统中都存在的优先级控制的公共子集。所有操作系统都理解“高”、“正常”、“低”和“空闲”优先级的概念。您可以简单地将这些一般概念映射到 Linux 和 BSD 衍生产品中的友好度范围。
    • 小心,Windows 示例与 POSIX 示例相反。一个不错的值 10 意味着低优先级。
    【解决方案3】:

    在每个类 Unix 平台(包括 Linux 和 MacOsX)上,请参阅 os.nice here

    os.nice(increment)
    Add increment to the process’s “niceness”. Return the new niceness. Availability: Unix.
    

    由于您已经有了适用于 Windows 的配方,它涵盖了大多数平台——在除 Windows 之外的任何地方使用肯定参数调用 os.nice,请在此处使用该配方。没有“完美打包”的跨平台解决方案 AFAIK(很难打包这个组合,但是,仅仅打包它会带来多少额外价值?-)

    【讨论】:

      【解决方案4】:

      如果您无权访问其中一些模块,您可以在 Windows 中使用:

      import os  
      def lowpriority():  
          """ Set the priority of the process to below-normal."""  
          os.system("wmic process where processid=\""+str(os.getpid())+"\" CALL   setpriority \"below normal\"")  
      
      

      为了兼容性,您可以像上面的示例一样明显区分操作系统类型。

      【讨论】: