2011-10-04 6 views
9

ho questo:Attendere un certo processo (conoscendo la "PID") end

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

Poi faccio questo:

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

credo che questo non è il modo migliore per aspettare il processo per terminare, ci deve essere qualche funzione di attesa o qualcosa del genere, ma non riesco a trovarlo.

di responsabilità: Il processo non è un processo figlio

risposta

8

In realtà non sono un programmatore Python, ma a quanto pare Python ha os.waitpid(). Questo dovrebbe consumare meno tempo della CPU e fornire una risposta molto più rapida rispetto, ad esempio, cercando di uccidere il processo a intervalli di un quarto di secondo.


Addendum: Come Niko sottolinea, os.waitpid() potrebbe non funzionare se il processo non è un figlio del processo corrente. In tal caso, utilizzare os.kill(pid, 0) potrebbe essere la soluzione migliore. Si noti che, in generale, ci sono tre possibili esiti di chiamare os.kill() su un processo:

  1. Se il processo esiste e appartiene a voi, la chiamata riesce.
  2. Se il processo esiste ma appartiene a un altro utente, genera un OSError con l'attributo errno impostato su errno.EPERM.
  3. Se il processo non esiste, viene generato un OSError con l'attributo errno impostato su errno.ESRCH.

Così, per controllare in modo affidabile se esiste un processo, si dovrebbe fare qualcosa di simile

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

Questo funziona solo per un processo figlio. Sarebbe bello se questo funzioni per qualsiasi processo. – Niko

+0

non avrò quel problema, ma buono a sapere che dettaglio: D – Niko

+1

Questo non funzionerà su Windows - il segnale di uccisione incondizionatamente uccide il processo inviato il segnale ([docs] (https://docs.python.org/2 /library/os.html#os.kill)). – dbn

1

import time, quindi utilizzare 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) 

Ho anche che esattamente stessa funzione in molti dei miei scrips di leggere /proc/#/cmdline per verificare la presenza di un PID.

+0

questo modo si evita il programma utilizza il 100% di uno dei nuclei della mia cpu, ho bevuto davvero notato che: P ma comunque dovrebbe esserci qualche funzione, tuttavia penso che questa soluzione non sia poi così male. – Niko

+0

Con il threading potresti fare un po 'meglio, ma diventa davvero complicato per questa semplice operazione e i thread hanno un overhead costoso. – chown

1

Dal momento che il metodo avrebbe funzionato solo su Linux, per il supporto Linux/osx, si potrebbe fare:

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) 

Modifica - Per il commento di TMC sui processi eccessivi

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

Non userebbe meno risorse (non ho testato), che elencare sul filesystem e aprire FD a tutti i risultati?

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

questo genererà una subshell, che genererà un processo per il comando ps, creando 8 processi al secondo. – tMC

+0

Cosa succede se la chiamata a os.system è stata sostituita con il metodo che usa [qui] (http://stackoverflow.com/questions/568271/check-if-pid-is-not-in-use-in-python/ 568285 # 568285)? – jdi

+0

È meglio che dichiarare/proc/ IMHO. – tMC