如何限制Python进程的I/O消耗(可能使用ionice)?
我希望一组特定的Python子进程对系统的影响尽可能小。我已经在使用nice来帮助限制CPU的使用。不过,理想情况下,输入输出(I/O)的使用也应该被限制。(如果你对此有疑问,请先假设这样做是有价值的;这些进程运行的时间长短无所谓,可能会有很多这样的进程,而且通常还有更高优先级的任务在同一台机器上运行等等。)
一个可能的解决方案是使用ionice
。有没有现成的Python包可以用来调用ionice
(谷歌搜索没有找到相关内容)?虽然写代码直接运行ionice
命令并不难,但我更希望能避免自己写别人已经写过/测试过的代码;有时候会有一些微妙的边缘情况等等。而且,是否还有更好的方法来限制I/O的使用呢?
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 个回答
为什么不让启动这些进程的程序直接给它们设置优先级(也就是用ionice命令来运行它们),而不是让进程自己去设置优先级呢?这样做看起来要简单很多。
嗯。
作为一个起点,你应该先找出在你的内核中,ioprio_set
和 ioprio_get
这两个系统调用对应的 syscall
编号。我建议你查看 /usr/include/asm/unistd_32.h
或者 /usr/include/asm/unistd_64.h
,具体取决于你的内核架构;如果在这两个文件里找不到,可以从 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
就这样,差不多就是这些。祝你玩得开心 :)
psutil 这个库提供了这个功能(适用于 Python 2.4 到 3.2 版本):
import psutil, os
p = psutil.Process(os.getpid())
p.ionice(psutil.IOPRIO_CLASS_IDLE)
另外,从 Python 3.3 开始,这个功能也会在 Python 的标准库中提供: http://bugs.python.org/issue10784