質問

subprocess.call を使用して Python プロセスから生成する外部コマンド ライン アプリが消費する時間と CPU を制限する必要があります。これは主に、生成されたプロセスがスタックして CPU が 99% に固定される場合があるためです。

nice と ulimit はこれを行うための合理的な方法のように思えますが、それらがサブプロセスとどのように対話するかはわかりません。

  • 制限は次のようになります。
    • 60 秒以上かかる場合はプロセスを強制終了します
    • CPU の 20% に制限する
  • サブプロセスを生成している Python プロセスではなく、サブプロセスにリソース制限を適用したいと考えています。

subprocess.call で生成されたプロセスに nice と ulimit を適用する方法はありますか?より良いPythonネイティブの代替手段はあるのでしょうか?

これは Linux (ubuntu) システム上です。

役に立ちましたか?

解決

あなたはこのようulimitniceシェルコマンドを持つサブプロセスの制限を設定することができます:

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 私はどういうわけかアレルギーがあります。おそらく私は年をとって不機嫌なだけかもしれませんが、そうならないように努めています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top