ZetCode

Python os.getpriority 函数

上次修改时间:2025 年 4 月 11 日

这份全面的指南探讨了 Python 的 os.getpriority 函数,该函数用于检索进程的调度优先级。我们将涵盖优先级值、进程选择和实际的系统监控示例。

基本定义

os.getpriority 函数返回指定进程的调度优先级。优先级会影响进程获得的 CPU 时间。

关键参数:which (进程选择:PRIO_PROCESS, PRIO_PGRP, PRIO_USER), who (进程 ID, 进程组 ID 或用户 ID)。 返回 nice 值。

获取当前进程优先级

os.getpriority 最简单的用法是检索当前进程的优先级。 这会显示新进程的默认 nice 值(通常为 0)。

current_priority.py
import os

# Get priority of current process
pid = os.getpid()
priority = os.getpriority(os.PRIO_PROCESS, pid)

print(f"Current process priority (PID {pid}): {priority}")

# Typical nice values range from -20 (highest) to 19 (lowest)
print(f"Priority range: -20 (highest) to 19 (lowest)")

此示例获取当前进程 ID 并查询其调度优先级。 优先级以 nice 值返回,其中数字越小表示优先级越高。

在类 Unix 系统上,只有特权进程才能设置负的 nice 值(更高的优先级)。 普通用户只能降低优先级。

获取另一个进程的优先级

我们可以通过指定其 PID 来检查任何正在运行的进程的优先级。 这需要适当的权限才能访问进程信息。

other_process_priority.py
import os

# Get priority of system processes (PID 1 is usually init/systemd)
try:
    init_priority = os.getpriority(os.PRIO_PROCESS, 1)
    print(f"Init process priority: {init_priority}")
except PermissionError:
    print("Cannot access init process priority (permission denied)")

# Get priority of parent process
parent_pid = os.getppid()
try:
    parent_priority = os.getpriority(os.PRIO_PROCESS, parent_pid)
    print(f"Parent process priority (PID {parent_pid}): {parent_priority}")
except ProcessLookupError:
    print("Parent process no longer exists")

此示例尝试获取 init 进程 (PID 1) 和父进程的优先级。 请注意,系统进程需要权限检查。

如果指定的进程不存在,则会引发 ProcessLookupError;如果权限不足,则会引发 PermissionError。

获取进程组优先级

使用 PRIO_PGRP,我们可以获取整个进程组的优先级。 这将返回组领导进程的优先级。

process_group_priority.py
import os

# Get current process group ID
pgid = os.getpgid(0)  # 0 means current process
print(f"Current process group ID: {pgid}")

# Get priority of the process group
try:
    group_priority = os.getpriority(os.PRIO_PGRP, pgid)
    print(f"Process group priority: {group_priority}")
except PermissionError:
    print("Cannot access process group priority")

# Compare with individual process priorities
current_priority = os.getpriority(os.PRIO_PROCESS, os.getpid())
print(f"Current process priority: {current_priority}")

此示例显示了如何获取进程组的优先级。 组优先级通常与组领导进程的优先级匹配。

进程组允许使用单个优先级设置命令管理多个相关进程。

获取用户进程优先级

使用 PRIO_USER,我们可以获取特定用户拥有的所有进程的默认优先级。 这显示了新进程的基本 nice 值。

user_priority.py
import os
import pwd

# Get current user ID
uid = os.getuid()
username = pwd.getpwuid(uid).pw_name

# Get user priority
try:
    user_priority = os.getpriority(os.PRIO_USER, uid)
    print(f"Default priority for user {username} (UID {uid}): {user_priority}")
except PermissionError:
    print(f"Cannot check priority for user {username}")

# Compare with root user (UID 0)
try:
    root_priority = os.getpriority(os.PRIO_USER, 0)
    print(f"Root user priority: {root_priority}")
except PermissionError:
    print("Cannot check root user priority")

此示例检索当前用户的优先级设置,并尝试检查 root 用户的优先级。 普通用户通常无法检查其他用户的优先级。

用户级别的优先级设置会影响该用户创建的所有新进程,除非显式更改。

监控优先级更改

此示例演示了通过比较修改进程优先级前后的值来监控优先级更改。

monitor_priority.py
import os
import time

pid = os.getpid()

def show_priority():
    try:
        return os.getpriority(os.PRIO_PROCESS, pid)
    except Exception as e:
        print(f"Error getting priority: {e}")
        return None

print(f"Initial priority: {show_priority()}")

# Try to increase priority (requires privileges)
try:
    os.setpriority(os.PRIO_PROCESS, pid, -5)
    print(f"After increasing priority: {show_priority()}")
except PermissionError:
    print("Cannot increase priority (requires root)")

# Decrease priority (normal users can do this)
os.setpriority(os.PRIO_PROCESS, pid, 10)
print(f"After decreasing priority: {show_priority()}")

该示例显示了如何监控优先级更改。 首先,它显示初始优先级,然后尝试提高它(通常在没有 root 权限的情况下失败),最后降低它。

os.setpriority 函数修改优先级,而 os.getpriority 检索当前值。

处理错误

此示例演示了使用 os.getpriority 时的正确错误处理,包括不存在的进程和权限问题的情况。

error_handling.py
import os

def safe_get_priority(pid):
    try:
        priority = os.getpriority(os.PRIO_PROCESS, pid)
        print(f"Priority for PID {pid}: {priority}")
    except ProcessLookupError:
        print(f"Process {pid} does not exist")
    except PermissionError:
        print(f"Cannot access priority for PID {pid} (permission denied)")
    except Exception as e:
        print(f"Unexpected error checking PID {pid}: {e}")

# Test with various PIDs
safe_get_priority(os.getpid())  # Current process
safe_get_priority(1)           # Init process (may need permissions)
safe_get_priority(99999)       # Non-existent process
safe_get_priority(0)           # Invalid PID

这个健壮的实现处理了检查进程优先级时所有潜在的错误情况。 它演示了针对不同场景的正确异常处理。

该函数优雅地处理了权限问题、不存在的进程以及可能发生的其他意外错误。

比较进程优先级

此示例比较多个进程的优先级,以确定哪个进程具有更高的调度优先级。

compare_priorities.py
import os

def compare_processes(pid1, pid2):
    try:
        prio1 = os.getpriority(os.PRIO_PROCESS, pid1)
        prio2 = os.getpriority(os.PRIO_PROCESS, pid2)
        
        if prio1 < prio2:
            print(f"PID {pid1} has higher priority ({prio1} vs {prio2})")
        elif prio1 > prio2:
            print(f"PID {pid2} has higher priority ({prio2} vs {prio1})")
        else:
            print(f"Both processes have equal priority ({prio1})")
    except Exception as e:
        print(f"Comparison failed: {e}")

# Compare current process with parent
current_pid = os.getpid()
parent_pid = os.getppid()
compare_processes(current_pid, parent_pid)

# Compare with system processes
compare_processes(current_pid, 1)  # Init process

此示例比较了两个进程的优先级。 较低的 nice 值意味着更高的优先级,因此我们检查哪个进程具有较小的值。

该比较有助于理解调度程序如何优先考虑争用 CPU 时间的不同进程。

安全注意事项

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程