Python - уменьшить ценность

Используя python, я могу легко увеличить привлекательность текущего процесса:

>>> import os
>>> import psutil

>>> # Use os to increase by 3
>>> os.nice(3)
3

>>> # Use psutil to set to 10
>>> psutil.Process(os.getpid()).nice(10)
>>> psutil.Process(os.getpid()).nice()
10

Однако уменьшение привлекательности процесса, по-видимому, недопустимо:

>>> os.nice(-1)
OSError: [Errno 1] Operation not permitted

>>> psutil.Process(os.getpid()).nice(5)
psutil.AccessDenied: psutil.AccessDenied (pid=14955)

Как правильно это сделать? И храповой механизм - ошибка или особенность?

4 ответа

Решение

Linux по умолчанию не позволяет непривилегированным пользователям уменьшать полезное значение (то есть увеличивать приоритет) своих процессов, чтобы один пользователь не создавал высокоприоритетный процесс, чтобы лишить других пользователей доступа. Python просто пересылает ошибку, которую ОС выдает в качестве исключения.

Пользователь root может повысить приоритет процессов, но запуск от имени root имеет другие последствия.

Это не ограничение Python или os.nice интерфейс. Это описано в man 2 nice что только суперпользователь может уменьшить привлекательность процесса:

nice () добавляет inc к значению nice для вызывающего процесса. (Более высокое значение nice означает низкий приоритет.) Только суперпользователь может указать отрицательное приращение или увеличение приоритета. Диапазон для хороших значений описан в getpriority(2).

Вы не можете уменьшить значение nice ниже 0 без sudo, но есть способ «отменить» ранее примененное значение nice и обойти «храповой механизм».

Обходной путь — использовать модуль threading. В приведенном ниже примере я запускаю функцию с именемrunв своем собственном потоке, и он сразу же устанавливает собственное значение nice равным 5. Когда он завершается, основной поток продолжает работать, ничего не делая очень быстро со значением nice, равным 0. Вы можете убедиться в этом, запустив команду top show threads сtop -H

      import os, threading

def run():
    os.nice(5)
    for x in range(500000000):
        x = x
    print("Done, going back to Nice 0")

thread = threading.Thread(target=run)
thread.start()
thread.join()

while True:
    x=1

У меня была такая же ошибка [Errno 2] Operation not permitted,

Я не хочу начинать свой сценарий с sudo, поэтому я нашел следующий способ:

def decrease_nice():
    pid = os.getpid()
    os.system("sudo renice -n -19 -p " + str(pid))

def normal_nice():
    pid = os.getpid()
    os.system("sudo renice -n 0 -p " + str(pid))
Другие вопросы по тегам