Pregunta

necesito para limitar la cantidad de tiempo de CPU y tomada por las aplicaciones de línea de comandos externos que desovan de un proceso de Python usando subprocess.call, sobre todo porque a veces el proceso generado se queda atascado y los pasadores de la CPU en un 99%.

agradable y ulimit parecen razonables maneras de hacer esto, pero no estoy seguro de cómo habían interactúan con subproceso.

  • Los límites de ser algo como:
    • Matar el proceso si está teniendo más de 60 segundos
    • limitarlo a 20% de la CPU
  • Quiero solicitar el recurso limitante para el subproceso, no al proceso de pitón que está generando los subprocesos.

¿Hay una manera de aplicar agradable y ulimit a la subprocess.call proceso generado? ¿Hay mejores alternativas pitón-natal?

Esto es en un sistema Linux (ubuntu).

¿Fue útil?

Solución

Puede establecer límites para subprocesos con los comandos de shell y ulimit nice como esta:

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

Esto ejecuta cpuhog con un límite de 60 segundos de tiempo de CPU y un ajuste de la amabilidad de 15. Nota que no hay manera simple de establecer un acelerador CPU 20% como tal. El proceso va a utilizar 100% de la CPU a menos que otra (menos bonito) proceso también necesita la CPU.

Otros consejos

Utilice el parámetro preexec_fn a subprocess.Popen, y el módulo de recursos. Ejemplo:

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 se bifurcará en un nuevo proceso. En el nuevo proceso, se llamará setLimits (), a continuación, exec child.py . Esto significa que el recurso estará limitado en el proceso hijo, pero no en los padres.

Salida cuando se ejecuta el programa:

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

Esto es en muchos casos una solución mejor que tratar de utilizar ulimit, ya que no es siempre una buena idea para desovar subproceso mediante el intérprete, sobre todo porque a menudo causa problemas parámetro fea citando.

Erik hizo fácil para mí, pero se olvidó la parte nice que Rich Señaló. Me parece que el paquete de psutil agradable (juego de palabras), pero por desgracia menos portátiles. Aquí está mi tomar ante la pregunta:

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 utiliza el shell=True a la que estoy de alguna manera alérgica. Tal vez sólo soy viejo y gruñón aquí, pero trato de evitarlo!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top