2010-07-26 51 views
12

Tôi đang sử dụng mô-đun đa python để đẻ trứng quá trình mớilấy pid của tiến trình con

như sau:

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

Tôi muốn để có được pid của lệnh iostat hoặc lệnh thực hiện sử dụng đa xử mô-đun

Khi tôi thực hiện:

d.pid 

nó cho tôi pid của subshell trong đó lệnh này đang chạy.

Mọi trợ giúp đều có giá trị.

Cảm ơn trước

Trả lời

1

Tôi nghĩ rằng với các module đa tiến bạn có thể gặp may vì bạn đang thực sự forking python trực tiếp và được cho rằng quá trình đối tượng thay vì quá trình bạn quan tâm ở dưới cùng của quá trình cây.

Một cách khác, nhưng có lẽ không phải cách tối ưu, để có được pid đó là sử dụng mô-đun psutil để tra cứu nó bằng cách sử dụng pid thu được từ đối tượng Process của bạn. Tuy nhiên, Psutil phụ thuộc vào hệ thống và sẽ cần được cài đặt riêng trên từng nền tảng đích của bạn.

Lưu ý: Hiện tại tôi không có máy tôi thường làm việc, vì vậy tôi không thể cung cấp mã làm việc hoặc chơi xung quanh để tìm một tùy chọn tốt hơn, nhưng sẽ chỉnh sửa câu trả lời này khi tôi có thể có thể làm điều này.

1

Ví dụ của bạn, bạn có thể sử dụng gói subprocess. Theo mặc định nó thực thi lệnh mà không vỏ (như os.system()) và cung cấp một PID:

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

Các Popen cũng cung cấp khả năng kết nối với đầu vào và đầu ra của quá trình tiêu chuẩn.

lưu ý: trước khi sử dụng shell=True, hãy lưu ý đến số security considerations.

+0

Nếu bạn muốn sử dụng subprocess.Popen mà không có sự lựa chọn vỏ, bạn không thể cung cấp cho nó một lệnh shell (như chuỗi duy nhất với nhiều tham số và một chuyển hướng đưa ra ở đây). – rakslice

6

Vì bạn dường như đang sử dụng Unix, bạn có thể sử dụng một ps lệnh nhanh chóng để có được các chi tiết của tiến trình con, như tôi đã làm ở đây (đây là Linux cụ thể):

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

Trên máy Mac: 'ps -o pid, ppid -ax | grep | cut -f 1 -d "" | tail -1' – Amit

+0

Gah, vâng, câu trả lời của tôi có lẽ là đặc trưng cho Linux. – rakslice

+0

Để nhận tất cả trẻ em đệ quy, bạn có thể sử dụng: 'subprocess.Popen ('pstree -p% d | perl -ne \' print" $ 1 "trong khi/\ ((\ d +) \)/g \ ''% parent_pid, shell = True, stdout = subprocess.PIPE) ' –

20

Tương tự như @ rakslice, bạn có thể sử dụng 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

Tại sao' os.kill (pid.pid, sig) 'thay vì' pid.send_signal (sig) '? Như trong, tại sao không sử dụng API psutil cho bạn? Ngoài ra, 'pid.send_signal' được cho là an toàn hơn vì nó nên tránh các điều kiện chủng tộc như khi quá trình ban đầu với kết thúc PID đã cho và một điều kiện khác sử dụng cùng một PID. – koniiiik

+0

Đồng ý. pid.send_signal (sig) có vẻ an toàn hơn. Cảm ơn bạn. – zhanxw

Các vấn đề liên quan