パイソン:ulimit と subprocess.call / subprocess.Popen に最適ですか?
質問
subprocess.call を使用して Python プロセスから生成する外部コマンド ライン アプリが消費する時間と CPU を制限する必要があります。これは主に、生成されたプロセスがスタックして CPU が 99% に固定される場合があるためです。
nice と ulimit はこれを行うための合理的な方法のように思えますが、それらがサブプロセスとどのように対話するかはわかりません。
- 制限は次のようになります。
- 60 秒以上かかる場合はプロセスを強制終了します
- CPU の 20% に制限する
- サブプロセスを生成している Python プロセスではなく、サブプロセスにリソース制限を適用したいと考えています。
subprocess.call で生成されたプロセスに nice と ulimit を適用する方法はありますか?より良いPythonネイティブの代替手段はあるのでしょうか?
これは Linux (ubuntu) システム上です。
解決
あなたはこのようulimit
とnice
シェルコマンドを持つサブプロセスの制限を設定することができます:
import subprocess
subprocess.Popen('ulimit -t 60; nice -n 15 cpuhog', shell=True)
これはCPU時間の60秒の限界と例えば20%のCPUスロットルを設定する簡単な方法がないこと15.注意のnice値調整とcpuhog
を実行します。別の(あまり素敵な)プロセスもCPUを必要としない限り、このプロセスは、100%のCPUを使用します。
他のヒント
subprocess.Popenにpreexec_fnに、パラメータ、およびリソースモジュールを使用してください。例:
のparent.py:の
#!/usr/bin/env python
import os
import sys
import resource
import subprocess
def setlimits():
# Set maximum CPU time to 1 second in child process, after fork() but before exec()
print "Setting resource limit in child (pid %d)" % os.getpid()
resource.setrlimit(resource.RLIMIT_CPU, (1, 1))
print "CPU limit of parent (pid %d)" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU)
p = subprocess.Popen(["./child.py"], preexec_fn=setlimits)
print "CPU limit of parent (pid %d) after startup of child" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU)
p.wait()
print "CPU limit of parent (pid %d) after child finished executing" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU)
のchild.py:の
#!/usr/bin/env python
import os
import sys
import resource
print "CPU limit of child (pid %d)" % os.getpid(), resource.getrlimit(resource.RLIMIT_CPU)
のparent.py の新しいプロセスにforkします。新しいプロセスでは、それはその後、のchild.py のexecし、)(setlimitsを呼び出します。これは、リソースは、子プロセスではなく、親に制限されることを意味します。
出力時に実行中のプログラムます:
./parent.py
CPU limit of parent (pid 17404) (-1, -1)
Setting resource limit in child (pid 17405)
CPU limit of parent (pid 17404) after startup of child (-1, -1)
CPU limit of child (pid 17405) (1, 1)
CPU limit of parent (pid 17404) after child finished executing (-1, -1)
これは、多くの場合、それはそれは多くの場合、トラブルを引用醜いパラメータを引き起こし、特に以来、シェル経由でサブプロセスを起動することは常に良いアイデアではありませんので、は、ulimitを使用しようとしているよりも優れたソリューションです。
エリック 私には簡単にしてくれましたが、彼は忘れてしまいました nice
どの部分 リッチ 指摘した。私はそれを見つけました psutil
パッケージは素晴らしい (冗談です) が、残念ながら移植性に欠けます。この質問に対する私の見解は次のとおりです。
import os
import psutil
import resource
import subprocess
def preexec_fn():
pid = os.getpid()
ps = psutil.Process(pid)
ps.set_nice(10)
resource.setrlimit(resource.RLIMIT_CPU, (1, 1))
print "mother pid", os.getpid()
p = subprocess.Popen(["./cpuhog.sh"], preexec_fn=preexec_fn)
p.wait()
print "mother still alive with pid", os.getpid()
ヴィル を使用しました shell=True
私はどういうわけかアレルギーがあります。おそらく私は年をとって不機嫌なだけかもしれませんが、そうならないように努めています。