ZetCode

Python os.setpriority Function

Last modified April 11, 2025

This comprehensive guide explores Python's os.setpriority function, which adjusts process scheduling priority. We'll cover priority levels, nice values, process selection, and practical examples for process management.

Basic Definitions

The os.setpriority function sets the scheduling priority of a process, process group, or user. It's available on Unix-like systems and affects CPU scheduling.

Key parameters: which (PRIO_PROCESS, PRIO_PGRP, PRIO_USER), who (process ID), priority (nice value from -20 to 19). Lower values mean higher priority.

Setting Current Process Priority

The simplest use of os.setpriority adjusts the current process's priority. This example demonstrates setting different nice values.

current_process.py
import os
import time

# Get current priority
current_nice = os.getpriority(os.PRIO_PROCESS, os.getpid())
print(f"Current nice value: {current_nice}")

# Set higher priority (lower nice value)
os.setpriority(os.PRIO_PROCESS, os.getpid(), -10)
print(f"New nice value: {os.getpriority(os.PRIO_PROCESS, os.getpid())}")

# CPU-intensive task
start = time.time()
for _ in range(10**7):
    pass
print(f"Execution time: {time.time() - start:.2f} seconds")

# Reset to default priority
os.setpriority(os.PRIO_PROCESS, os.getpid(), 0)

This example first gets the current nice value, then increases priority. Note that setting negative values typically requires superuser privileges.

The CPU-bound task may run faster with higher priority, though results vary based on system load and scheduler implementation.

Setting Child Process Priority

You can set priority for child processes after creation. This example spawns a child and adjusts its priority separately from the parent.

child_process.py
import os
import time

def worker():
    print(f"Child PID: {os.getpid()}")
    start = time.time()
    for _ in range(10**7):
        pass
    print(f"Child execution time: {time.time() - start:.2f}")

pid = os.fork()
if pid == 0:  # Child process
    worker()
else:  # Parent process
    # Set child to lower priority (higher nice value)
    os.setpriority(os.PRIO_PROCESS, pid, 10)
    print(f"Set child {pid} to nice value 10")
    
    # Parent continues with default priority
    start = time.time()
    for _ in range(10**7):
        pass
    print(f"Parent execution time: {time.time() - start:.2f}")

The parent process sets the child to a lower priority (nice value 10) while keeping normal priority for itself. This may cause the parent to complete first.

Note that fork() is Unix-specific. On Windows, use multiprocessing instead.

Setting Process Group Priority

os.setpriority can adjust priority for an entire process group. This affects all processes in the group, useful for batch operations.

process_group.py
import os
import time

# Create new process group
os.setpgid(0, 0)
pgid = os.getpgid(0)

print(f"Process group ID: {pgid}")

# Set priority for entire group
os.setpriority(os.PRIO_PGRP, pgid, 5)

# Verify setting
print(f"Group nice value: {os.getpriority(os.PRIO_PGRP, pgid)}")

# Child processes inherit group priority
for _ in range(3):
    pid = os.fork()
    if pid == 0:
        print(f"Child {os.getpid()} nice: {os.getpriority(os.PRIO_PROCESS, 0)}")
        time.sleep(1)
        os._exit(0)

# Wait for children
for _ in range(3):
    os.wait()

This creates a new process group and sets its priority. Child processes automatically inherit the group's priority setting.

Process groups are useful when you need to manage multiple related processes as a single unit.

Setting User Process Priority

The PRIO_USER option sets priority for all processes owned by a user. This requires superuser privileges and affects all current and future processes.

user_priority.py
import os
import pwd

try:
    # Get user ID for 'nobody'
    user_id = pwd.getpwnam('nobody').pw_uid
    
    # Set priority for all user's processes
    os.setpriority(os.PRIO_USER, user_id, 10)
    print(f"Set nice value 10 for user nobody")
    
    # Verify setting
    current = os.getpriority(os.PRIO_USER, user_id)
    print(f"Current nice value for user: {current}")
    
except PermissionError:
    print("Error: Requires superuser privileges")
except KeyError:
    print("Error: User nobody not found")

This attempts to set a lower priority for all processes owned by the 'nobody' user. Note this requires root privileges and affects all user's processes.

Use this capability carefully as it can significantly impact system performance for the affected user.

Handling Permission Errors

Setting high priority (negative nice values) typically requires elevated privileges. This example demonstrates proper error handling.

permission_handling.py
import os
import sys

def set_high_priority():
    try:
        os.setpriority(os.PRIO_PROCESS, 0, -10)
        print("Successfully set high priority")
    except PermissionError:
        print("Permission denied: need superuser privileges")
        # Fall back to maximum allowed priority
        min_nice = os.getpriority(os.PRIO_PROCESS, 0)
        if min_nice > 0:
            os.setpriority(os.PRIO_PROCESS, 0, 0)
            print("Set to default priority instead")
        else:
            os.setpriority(os.PRIO_PROCESS, 0, min_nice)
            print(f"Set to minimum allowed nice value: {min_nice}")

if __name__ == "__main__":
    set_high_priority()

This attempts to set high priority, falling back to the best allowed priority if permission is denied. The approach gracefully degrades functionality.

Always handle permission errors when working with process priorities, as availability depends on user privileges.

Cross-Platform Considerations

Process priority handling differs across platforms. This example demonstrates a cross-platform compatible approach using try/except.

cross_platform.py
import os
import sys
import platform

def set_low_priority():
    """Set process to low priority, works across platforms"""
    system = platform.system()
    
    try:
        if system == "Windows":
            import win32api
            import win32process
            import win32con
            
            pid = win32api.GetCurrentProcessId()
            handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
            win32process.SetPriorityClass(handle, win32process.BELOW_NORMAL_PRIORITY_CLASS)
        else:  # Unix-like
            os.setpriority(os.PRIO_PROCESS, 0, 10)  # Low priority
            
        print("Successfully set low priority")
    except Exception as e:
        print(f"Failed to set priority: {str(e)}")

if __name__ == "__main__":
    set_low_priority()

This checks the operating system and uses the appropriate method for setting process priority. Windows requires pywin32 for similar functionality.

The example shows how to maintain functionality across different platforms while handling potential errors gracefully.

Priority and CPU Affinity

Combining priority settings with CPU affinity can optimize performance. This example demonstrates both techniques on Linux.

priority_affinity.py
import os
import time

def set_cpu_affinity(cpus):
    """Set CPU affinity mask (Linux only)"""
    mask = 0
    for cpu in cpus:
        mask |= 1 << cpu
    os.sched_setaffinity(0, [mask])

try:
    # Set high priority
    os.setpriority(os.PRIO_PROCESS, 0, -5)
    
    # Restrict to CPU 0
    set_cpu_affinity([0])
    
    # Performance test
    start = time.time()
    for _ in range(10**7):
        pass
    duration = time.time() - start
    
    print(f"Execution time: {duration:.2f} seconds")
    
except PermissionError:
    print("Need root privileges for high priority setting")
except AttributeError:
    print("CPU affinity not supported on this platform")

This combines high priority with CPU affinity to potentially improve performance for CPU-bound tasks. Both operations may require special privileges.

CPU affinity restricts the process to specific cores, while priority affects scheduling within those cores.

Security Considerations

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.