2010-07-26 3 views
12

Sto usando il modulo multiprocessing Python per deporre le uova nuovo processoottenendo pid del processo figlio

come segue:

import multiprocessing 
import os 
d = multiprocessing.Process(target=os.system,args=('iostat 2 > a.txt',)) 
d.start() 

voglio ottenere pid del comando iostat oppure il comando eseguito utilizzando multiprocessing modulo

Quando eseguo:

d.pid 

mi dà il pid di subshell in cui questo comando è in esecuzione.

Qualsiasi aiuto sarà prezioso.

Grazie in anticipo

risposta

1

penso che con il modulo multiprocesso si potrebbe essere fuori di fortuna dato che si sta davvero fork pitone direttamente e sono dato che oggetto di processo invece del processo siete interessati alla parte inferiore del processo albero.

Un modo alternativo, ma forse non ottimale, per ottenere che il pid sia utilizzare il modulo psutil per cercarlo usando il pid ottenuto dall'oggetto Process. Psutil, tuttavia, dipende dal sistema e dovrà essere installato separatamente su ciascuna delle piattaforme di destinazione.

Nota: al momento non lavoro su una macchina da cui lavoro, quindi non posso fornire codice di lavoro o giocare per trovare un'opzione migliore, ma modificherò questa risposta quando posso per mostrare come potresti essere in grado di farlo.

1

Per l'esempio è possibile utilizzare il pacchetto subprocess. Per default esegue il comando senza guscio (come os.system()) e fornisce un PID:

from subprocess import Popen 
p = Popen('iostat 2 > a.txt', shell=True) 
processId = p.pid 
p.communicate() # to wait until the end 

Il Popen fornisce anche la capacità di collegamento all'ingresso e all'uscita del processo standard.

nota: prima di utilizzare shell=True essere a conoscenza dello security considerations.

+0

Se si desidera utilizzare subprocess.Popen senza l'opzione di shell, non è possibile dare un comando di shell (come la singola stringa con più parametri e un reindirizzamento mostrato qui). – rakslice

6

Dal momento in cui sembra essere utilizzando Unix, è possibile utilizzare un comando rapido ps per ottenere i dettagli dei processi secondari, come ho fatto io qui (questo è specifico di Linux):

import subprocess, os, signal 

def kill_child_processes(parent_pid, sig=signal.SIGTERM): 
     ps_command = subprocess.Popen("ps -o pid --ppid %d --noheaders" % parent_pid, shell=True, stdout=subprocess.PIPE) 
     ps_output = ps_command.stdout.read() 
     retcode = ps_command.wait() 
     assert retcode == 0, "ps command returned %d" % retcode 
     for pid_str in ps_output.split("\n")[:-1]: 
       os.kill(int(pid_str), sig) 
+0

Su un Mac: 'ps -o pid, ppid -ax | grep | cut -f 1 -d "" | coda -1' – Amit

+0

Gah, sì, la mia risposta è probabilmente specifica per Linux. – rakslice

+0

Per ottenere tutti i bambini in modo ricorsivo, è possibile utilizzare: 'sottoprocesso.Popen ('pstree -p% d | perl -ne \' stampa" $ 1 "mentre/\ ((\ d +) \)/g \ ''% parent_pid, shell = True, stdout = subprocess.PIPE) ' –

20

Simile a @ rakslice, è possibile utilizzare psutil:

import signal, psutil 
def kill_child_processes(parent_pid, sig=signal.SIGTERM): 
    try: 
     parent = psutil.Process(parent_pid) 
    except psutil.NoSuchProcess: 
     return 
    children = parent.children(recursive=True) 
    for process in children: 
     process.send_signal(sig) 
+1

Perché' os.kill (pid.pid, sig) 'invece di' pid.send_signal (sig) '? Come in, perché non usare l'API psutil ti ha già dato? Inoltre, 'pid.send_signal' è presumibilmente più sicuro in quanto dovrebbe evitare condizioni di gara come quando il processo originale con il PID specificato termina e un altro utilizza lo stesso PID. – koniiiik

+0

Accetto. pid.send_signal (sig) sembra più sicuro. Grazie. – zhanxw