É possível renunciar um subprocesso?
-
20-09-2019 - |
Pergunta
Eu sei sobre os.nice()
Funciona perfeito para o processo dos pais, mas preciso fazer Renice dos subprocessos do meu filho. Encontrei uma maneira de fazer isso, mas parece não ser muito útil e excessivo demais:
os.system("renice -n %d %d" % ( new_nice, suprocess.pid ) )
E não é o retorno resultante de bom nível após a reinicialização.
Existe uma maneira mais limpa de renicear subprocessos em Python?
Solução
Use o preexec_fn
parâmetro de subprocess.Popen
:
Se
preexec_fn
está definido como um objeto chamável, esse objeto será chamado no processo infantil pouco antes da criança ser executada. (Somente Unix)
Exemplo:
>>> Popen(["nice"]).communicate()
0
(None, None)
>>> Popen(["nice"], preexec_fn=lambda : os.nice(10)).communicate()
10
(None, None)
>>> Popen(["nice"], preexec_fn=lambda : os.nice(20)).communicate()
19
(None, None)
Outras dicas
Você deveria usar subprocess.Popen
ao invés de os.system
, para que você possa acessar quaisquer resultados impressos no sys.stdout. Iirc, os.system
apenas fornece acesso ao valor de retorno, que provavelmente é '0' e não o bom nível.
Renice é geralmente implementado por set/getPriority , o que parece não ter entrado no módulo Python OS ou Posix (ainda?). Então, chamar o comando do sistema Renice parece ser a sua melhor aposta agora.
Como alternativa, você pode fazer com que os pais antes de criar um processo filho - que herdará seus pais de bom valor - e os.nice de volta depois de criar o processo filho.
Sem direitos adequados, você pode renicear apenas de uma maneira
Eu criei um script python com uma CLI no passado. Você pode encontrá-lo aqui: https://github.com/jedie/python-code-snippets/blob/master/codesnippets/reniceall.py
Renice é geralmente implementado pelo Set/GetPriority, que parece não ter entrado no módulo Python OS ou Posix (ainda?). Então, chamar o comando do sistema Renice parece ser a sua melhor aposta agora.
Expandindo o comentário de Daniel sobre ctypes
:
from ctypes import cdll
libc = cdll.LoadLibrary("libc.so.6")
for pid in pids:
print("old priority for PID", pid, "is", libc.getpriority(0, pid))
libc.setpriority(0, pid, 20)
print("new priority for PID", pid, "is", libc.getpriority(0, pid))
Resultado:
old priority for PID 9721 is 0
new priority for PID 9721 is 19