Frage

Ich brauche die Menge an Zeit und CPU von externen Befehlszeilen apps, die ich von einem Python-Prozess unter Verwendung von subprocess.call laichen genommen zu begrenzen, vor allem, weil manchmal der erzeugte Prozess stecken bleibt und PINs die CPU bei 99%.

schön und ulimit scheinen, wie vernünftige Möglichkeiten, dies zu tun, aber ich bin nicht sicher, wie sie mit subprocess interagieren würden.

  • Die Grenzen in etwa so aussehen:
    • Tötet den Prozess, wenn es länger als 60 Sekunden unter
    • Grenzwert auf 20% der CPU-
  • Ich mag die Ressource gilt für den Teilprozess zu beschränken, nicht auf den Python-Prozess, der die Teilprozesse ist das Laichen.

Gibt es eine Möglichkeit schön und ulimit zum subprocess.call anzuwenden Prozess erzeugt? Gibt es bessere Python-native Alternativen?

Dies ist auf einem Linux (ubuntu) System.

War es hilfreich?

Lösung

Sie können Grenzwerte für Teilprozesse mit den ulimit und nice Shell-Befehlen wie folgt festgelegt:

import subprocess
subprocess.Popen('ulimit -t 60; nice -n 15 cpuhog', shell=True)

Dies läuft cpuhog mit einer Grenze von 60 Sekunden CPU-Zeit und einer Nettigkeit Einstellung der 15. Man beachte, dass es keine einfache Möglichkeit ist, eine 20% Drossel CPU als solche einzustellen. Der Prozess wird 100% CPU verwenden, es sei denn, eine andere (weniger schön) Prozess muss auch die CPU.

Andere Tipps

Mit dem preexec_fn Parameter subprocess.Popen, und das Ressourcenmodul. Beispiel:

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 wird in einen neuen Prozess Gabel. Bei dem neuen Verfahren wird es nennen setlimits (), dann exec child.py . Das bedeutet, die Ressource in dem untergeordneten Prozess begrenzt werden, aber nicht in den übergeordneten.

Ausgabe beim Laufen Programm:

./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)

Dies ist in vielen Fällen eine bessere Lösung als zu versuchen, ulimit zu verwenden, da es nicht immer eine gute Idee ist subprocess über Shell zum Laichen, zumal es hässlich Parameter zitieren Probleme verursacht oft.

Erik machte es einfach für mich, aber er vergaß den nice Teil der Reich aufgezeigt. Ich finde das psutil Paket schön (Wortspiel beabsichtigt), aber leider weniger tragbar. Hier ist mein nehmen auf die Frage:

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()

Ville verwendet, um die shell=True, auf die ich irgendwie allergisch bin. Ich bin vielleicht nur alt und mürrisch hier, aber ich versuche es zu vermeiden!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top