Pergunta

Eu preciso limitar a quantidade de tempo e cpu tomada pela linha de comando externo aplicativos que eu desova de um processo de python usando subprocess.call, principalmente porque, por vezes, o processo gerado fica preso e pins da CPU em 99%.

agradável e ulimit parecer maneiras razoáveis ??de fazer isso, mas não tenho certeza de como eles interagem com subprocesso.

  • Os limites algo como:
    • matar o processo se ele está tomando mais de 60 segundos
    • limitá-lo a 20% da cpu
  • Eu quero aplicar o recurso limitante ao subprocesso, não para o processo de python que está gerando os subprocessos.

Existe uma maneira de aplicar agradável e ulimit para o processo subprocess.call gerou? Existem alternativas melhores python-natal?

Esta é em um sistema Linux (Ubuntu).

Foi útil?

Solução

Você pode definir limites para subprocessos com os ulimit e nice comandos shell como este:

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

Este é executado cpuhog com um limite de 60 segundos de tempo de CPU e um ajuste de niceness de 15. Note que não há nenhuma maneira simples de definir um acelerador CPU 20% como tal. O processo vai usar 100% da CPU, a menos que outro processo (menos bom) também precisa da CPU.

Outras dicas

Use o parâmetro preexec_fn para subprocess.Popen, eo módulo de recursos. Exemplo:

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 seguirão em um novo processo. No novo processo, ele irá chamar setlimits (), em seguida, exec child.py . Isto significa que o recurso será limitado no processo de criança, mas não no pai.

Saída durante a execução do 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)

Esta é em muitos casos uma solução melhor do que tentar usar ulimit, uma vez que nem sempre é uma boa idéia para subprocess desova via shell, especialmente desde que muitas vezes provoca parâmetro problemas citando feio.

Erik tornou fácil para mim, mas ele esqueceu a parte nice quais Rico out Pointed. I encontrar o pacote agradável psutil (trocadilho intencional), mas, infelizmente, menos portátil. Aqui é a minha opinião com a pergunta:

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 usou o shell=True para o qual eu sou de alguma forma alérgica. Talvez eu sou apenas velho e mal-humorado aqui, mas tento evitá-lo!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top