2009-03-31 7 views
13

私は、Pythonのサブプロセスの特定のセットをできるだけ影響の少ないものにしたいと思います。私は既にniceを使ってCPU消費を制限しています。しかし理想的にはI/Oも制限されます。 (懐疑的であれば、私にユーモアを与えて、これを行うことに価値があると仮定してください;実行にどれくらい時間がかかりますか、それらの多くがある可能性があります。同じマシンなど)PythonプロセスのI/O消費を制限する方法(おそらくioniceを使用しています)?

ioniceの可能性があります。 ioniceを呼び出すための既存のPythonパッケージはありますか(Googleは何も出せませんでした)? ioniceコマンドを実行するだけでコードを書くのは難しくありません。私は誰かが書いた/テストしたコードを書くことを避けることを好むでしょう。時には微妙なエッジケースなどがあります。また、I/O消費を制限する良い方法がありますか?

man page for ioniceionice値が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 

答えて

14

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

+0

クールな修正は、OSXで利用できるようにしたいと考えています。 –

+0

ええええええええええええと、OSXはそれをネイティブに公開していません。 –

+0

ブロックデバイスにCFQスケジューラがあることを確認してください。それ以外の場合は動作しません。 – Zorg

3

起動プロセスは、それらの上にionice(すなわち、Rを行うものは何でも持っていないのはなぜそれらをイオン化するのではなく)全体的にきれいに見える。

+0

私が効果的exec(例えば、 'multiprocessing'モジュールを使用して)ではなくforkしたい。どこにイオンが入るのかは不明です。子供たちはionice -p -cblahを呼び出すことができます(それ自体では、例えばos.systemを使って)。 –

5

hm。

開始ポインタとして、カーネル内のioprio_setioprio_getのシステムコールが何であるかを見つける必要があります。あなたのカーネルアーチに応じて、/usr/include/asm/unistd_32.hまたは/usr/include/asm/unistd_64.hをチェックインすることをお勧めします。存在しない場合は、syscall(2)のマニュアルページ(/usr/include/sys/syscall.hである必要があります)を参考にして作業を開始してください。

あなたは​​を使用する必要があり、ことを考えると、アラカルト:

多かれ少なかれ、それだけです
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 

。楽しい:)

関連する問題