Можно ли арендовать подпроцесс?
Я знаю о os.nice()
это прекрасно работает для родительского процесса, но мне нужно сделать рениз моего дочернего подпроцесса. Я нашел способ сделать это, но это, кажется, не очень удобно и слишком излишне:
os.system("renice -n %d %d" % ( new_nice, suprocess.pid ) )
И это не вернет результат хороший уровень после сдачи в аренду.
Есть ли более чистый способ перекомпоновки подпроцессов в Python?
7 ответов
Использовать preexec_fn
параметр subprocess.Popen
:
Если
preexec_fn
устанавливается в вызываемый объект, этот объект будет вызываться в дочернем процессе непосредственно перед выполнением дочернего процесса. (Только для Unix)
Пример:
>>> Popen(["nice"]).communicate()
0
(None, None)
>>> Popen(["nice"], preexec_fn=lambda : os.nice(10)).communicate()
10
(None, None)
>>> Popen(["nice"], preexec_fn=lambda : os.nice(20)).communicate()
19
(None, None)
Вы должны использовать subprocess.Popen
вместо os.system
, так что вы можете получить доступ к любым результатам, напечатанным в sys.stdout. IIRC, os.system
только дает вам доступ к возвращаемому значению, которое, вероятно, равно 0, а не хорошему уровню.
renice обычно реализуется с помощью set / getpriority, который, похоже, не вошел в модуль python os или posix (пока?). Поэтому вызов команды renice system кажется вам лучшим выбором.
В качестве альтернативы вы можете использовать os.nice для родительского элемента перед созданием дочернего процесса, который унаследует значение nice для своих родителей, и снова возвращать os.nice после создания дочернего процесса.
Я создал сценарий Python с CLI в прошлом. Вы можете найти его здесь: https://github.com/jedie/python-code-snippets/blob/master/CodeSnippets/reniceall.py
renice обычно реализуется с помощью set/getpriority, который, похоже, не вошел в модуль python os или posix (пока?). Поэтому вызов команды renice system кажется вам лучшим выбором.
Расширяя комментарий Даниила о ctypes
:
from ctypes import cdll
libc = cdll.LoadLibrary("libc.so.6")
for pid in pids:
print("old priority for PID", pid, "is", libc.getpriority(0, pid))
libc.setpriority(0, pid, 20)
print("new priority for PID", pid, "is", libc.getpriority(0, pid))
Результат:
old priority for PID 9721 is 0
new priority for PID 9721 is 19
Без надлежащих прав вы можете арендовать только одним способом
Если вы хотите изменить приятность подпроцесса без изменения родителя, вы можете запустить функцию, которая запускает команду подпроцесса с библиотекой потоков .
import threading, subprocess
def run():
os.nice(5)
subprocess.run(['sha256sum', '/dev/urandom'])
thread = threading.Thread(target=run)
thread.start()