python resources nice ulimit

Python: ulimit y agradable para subprocess.call/subprocess.Popen?



resources nice (3)

Use el parámetro preexec_fn para subprocesar.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 integrará en un nuevo proceso. En el nuevo proceso, llamará a setlimits (), luego a exec child.py . Esto significa que el recurso estará limitado en el proceso hijo, pero no en el padre.

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)

En muchos casos, esta es una solución mejor que tratar de usar ulimit, ya que no siempre es una buena idea generar subprocesos a través de shell, especialmente porque a menudo causa problemas de citas de parámetros desagradables.

Necesito limitar la cantidad de tiempo y la CPU tomadas por las aplicaciones externas de línea de comando que genero de un proceso de python usando subprocess.call, principalmente porque a veces el proceso engendrado se atasca y fija la CPU al 99%.

nice y ulimit parecen formas razonables de hacerlo, pero no estoy seguro de cómo interactuarían con el subproceso.

  • Los límites se ven algo así como:
    • Mata el proceso si lleva más de 60 segundos
    • Limítelo al 20% de la CPU
  • Quiero aplicar la limitación de recursos al subproceso, no al proceso de Python que está generando los subprocesos.

¿Hay alguna forma de aplicar nice y ulimit al proceso subprocess.call generado? ¿Hay mejores alternativas nativas de pitón?

Esto está en un sistema Linux (ubuntu).


Erik me lo hizo fácil, pero se olvidó de la nice parte que Rich señalaba. psutil paquete psutil me parece agradable (juego de palabras) pero desafortunadamente menos portátil. Aquí está mi opinión sobre 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 usó el shell=True para el cual soy alérgico de alguna manera. Tal vez estoy viejo y gruñón aquí, ¡pero trato de evitarlo!


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

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 bondad de 15. Tenga en cuenta que no hay una manera simple de configurar un 20% de aceleración de la CPU como tal. El proceso usará 100% de CPU a menos que otro proceso (menos agradable) también necesite la CPU.