Как ограничить потребление ввода-вывода процессов Python (возможно, используя ionice)? - PullRequest
13 голосов
/ 31 марта 2009

Мне бы хотелось, чтобы конкретный набор подпроцессов Python был как можно менее эффективным. Я уже использую nice , чтобы помочь ограничить потребление ресурсов процессора. Но в идеале ввод-вывод также будет ограничен. (Если вы настроены скептически, пожалуйста, позабавьте меня и предположите, что в этом есть смысл; не имеет значения, сколько времени они занимают, их может быть много, и есть вещи с более высоким приоритетом (обычно) та же машина и т. д.)

Одной из возможностей является ionice. Существуют ли какие-либо пакеты Python для вызова ionice (Google ничего не обнаружил)? Нетрудно написать код для простого запуска команды ionice; но я бы предпочел не писать код, который кто-то другой написал / протестировал; иногда есть тонкие граничные случаи и т. д. И есть ли лучший способ ограничить потребление ввода-вывода?

Страница man для ionice предполагает, что значение ionice может зависеть от значения nice, но запуск этого скрипта Python 2.6, по-видимому, опровергает это, даже для дочерних процессов, где nice значение наследуется:

#!/usr/bin/env python

import os
import multiprocessing

def print_ionice(name):
    print '*** ', name, ' ***'
    os.system("echo -n 'nice: '; nice")
    os.system("echo -n 'ionice: '; ionice -p%d" % os.getpid())

for niced in (None, 19):
    if niced: os.nice(niced)
    print '**** niced to: ', niced, ' ****'
    print_ionice('parent')
    subproc = multiprocessing.Process(target=print_ionice, args=['child'])
    subproc.start()
    subproc.join()

Который имеет следующий вывод:

$ uname -as
Linux x.fake.org 2.6.27-11-server #1 SMP Thu Jan 29 20:13:12 UTC 2009 x86_64 GNU/Linux
$ ./foo.py
**** niced to:  None  ****
***  parent  ***
nice: 0
ionice: none: prio 4
***  child  ***
nice: 0
ionice: none: prio 4
**** niced to:  19  ****
***  parent  ***
nice: 19
ionice: none: prio 4
***  child  ***
nice: 19
ionice: none: prio 4

Ответы [ 3 ]

14 голосов
/ 05 июня 2011

psutil предоставляет эту функциональность (python 2.4 -> 3.2):

import psutil, os
p = psutil.Process(os.getpid())
p.ionice(psutil.IOPRIO_CLASS_IDLE)

Также, начиная с Python 3.3, это будет доступно и в python stdlib: http://bugs.python.org/issue10784

5 голосов
/ 01 апреля 2009

Hm.

В качестве начального указателя вы должны найти, какие syscall числа являются системными вызовами ioprio_set и ioprio_get в вашем ядре. Я бы посоветовал вам зарегистрироваться в /usr/include/asm/unistd_32.h или /usr/include/asm/unistd_64.h, в зависимости от вашей арки ядра; если нет, начните с предложения * man-страницы syscall(2), которая должна быть /usr/include/sys/syscall.h, и пройдите вниз.

Учитывая это, вы должны использовать ctypes, а-ля:

def ioprio_set(which, who, ioprio):
    rc= ctypes.CDLL('libc.so.6').syscall(289, which, who, ioprio)
    # some error checking goes here, and possibly exception throwing

Вот так, более или менее. Веселитесь:)

3 голосов
/ 31 марта 2009

Почему бы не сделать то, что запускает , процессы делают на них ионизацию (т. Е. Запускают их с ионизацией), а не заставляют их самим ионизировать? Кажется, намного чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...