2011-10-04 19 views
9

tengo esto:Esperar a que un determinado proceso (conociendo el "PID") final

def get_process(): 
    pids = [] 
    process = None 
    for i in os.listdir('/proc'): 
     if i.isdigit(): 
      pids.append(i) 

    for pid in pids: 
     proc = open(os.path.join('/proc', pid, 'cmdline'), 'r').readline() 
     if proc == "Something": 
      process = pid 

    return process   

def is_running(pid): 
    return os.path.exists("/proc/%s" % str(pid)) 

Entonces hago esto:

process = get_process() 
if process == None: 
    #do something 
else: 
    #Wait until the process end 
    while is_running(process): 
     pass 

creo que esto no es la mejor manera de esperar el proceso para terminar, debe haber alguna función de espera o algo, pero no puedo encontrarlo.

de responsabilidad: El proceso no es un proceso hijo

Respuesta

8

realmente no soy un programador de Python, Python, pero al parecer sí tiene os.waitpid(). Eso debería consumir menos tiempo de CPU y proporcionar una respuesta mucho más rápida que, por ejemplo, intentar matar el proceso a intervalos de un cuarto de segundo.


Adición: Como Niko señala, os.waitpid() puede no funcionar si el proceso no es un hijo del proceso actual. En ese caso, usar os.kill(pid, 0) puede ser la mejor solución. Tenga en cuenta que, en general, hay tres posibles resultados de llamar os.kill() en un proceso:

  1. Si el proceso existe y pertenece a usted, la llamada se realiza correctamente.
  2. Si el proceso existe pero pertenece a otro usuario, arroja un OSError con el atributo errno establecido en errno.EPERM.
  3. Si el proceso no existe, arroja un OSError con el atributo errno establecido en errno.ESRCH.

Por lo tanto, para comprobar con certeza si existe un proceso, usted debe hacer algo como

def is_running(pid):   
    try: 
     os.kill(pid, 0) 
    except OSError as err: 
     if err.errno == errno.ESRCH: 
      return False 
    return True 
+1

Eso solo funciona para un proceso secundario. Sería genial si esto funciona para cualquier proceso. – Niko

+0

no tendré ese problema pero es bueno saber ese detalle: D – Niko

+1

Esto no funcionará en Windows - la señal de muerte mata incondicionalmente el proceso enviado la señal ([documentos] (https://docs.python.org/2) /library/os.html#os.kill)). – dbn

1

import time, a continuación, utilizar time.sleep(#):

import time 
process = get_process() 
if process == None: 
    #do something 
else: 
    #Wait until the process end 
    while is_running(process): 
        time.sleep(0.25) 

también tengo que exactamente la misma función en varios de mis scripts para leer a través /proc/#/cmdline para comprobar si hay una PID.

+0

Esto evita que el programa utiliza el 100% de uno de los núcleos de mi cpu, divertían realmente cuenta de que: P pero de todos modos debería haber alguna función, sin embargo, creo que esta solución no es tan mala. – Niko

+0

Con el subprocesamiento se puede hacer algo mejor, pero se complica demasiado para esta simple tarea y los subprocesos tienen costosos gastos generales. – chown

1

Dado que este método sólo funciona en Linux, para el soporte de Linux/OSX, usted podría hacer:

import time 
import os 

def is_running(pid): 
    stat = os.system("ps -p %s &> /dev/null" % pid) 
    return stat == 0 

pid = 64463 

while is_running(pid): 
    time.sleep(.25) 

Editar - por el comentario de TMC sobre los procesos excesivos

Referencing: How to check if there exists a process with a given pid in Python?

¿No utilizaría esto menos recursos (no he probado), que enumerar en el sistema de archivos y abrir los FD a todos los resultados?

import time 
import os 

def is_running(pid):   
    try: 
     os.kill(pid, 0) 
    except OSError: 
     return False 

    return True 

pid = 64463 

while is_running(pid): 
    time.sleep(.25) 
+0

esto generará una subshell, que generará un proceso para el comando ps, creando 8 procesos por segundo. – tMC

+0

¿Qué pasa si la llamada a os.system fue reemplazada por el método que usa [aquí] (http://stackoverflow.com/questions/568271/check-if-pid-is-not-in-use-in-python/ 568285 # 568285)? – jdi

+0

Eso es mejor que declarar/proc/ en mi humilde opinión. – tMC

Cuestiones relacionadas