2008-10-06 33 views
8

Một tập lệnh python cần phải sinh ra nhiều tiến trình con thông qua fork(). Tất cả các tiến trình con đó sẽ chạy đồng thời và quá trình cha mẹ nên đợi tất cả chúng hoàn tất. Có khả năng để thiết lập một số thời gian chờ trên một "chậm" con sẽ được tốt đẹp. Quy trình gốc sẽ xử lý phần còn lại của tập lệnh sau khi tất cả trẻ em được thu thập.Cách tốt nhất để chạy nhiều quy trình con thông qua fork() là gì?

Cách tốt nhất để làm việc đó là gì? Cảm ơn.

Trả lời

10

đơn giản ví dụ:

import os 
chidren = [] 
for job in jobs: 
    child = os.fork() 
    if child: 
     children.append(child) 
    else: 
     pass # really should exec the job 
for child in children: 
    os.waitpid(child, 0) 

Timing ra một đứa trẻ chậm là công việc nhiều hơn một chút; bạn có thể sử dụng wait thay vì waitpid và hủy các giá trị được trả lại từ danh sách trẻ em, thay vì chờ đợi từng giá trị một lần lượt (như ở đây). Nếu bạn thiết lập một số alarm với trình xử lý SIGALRM, bạn có thể chấm dứt việc chờ sau một thời gian trễ cụ thể. Đây là tất cả các công cụ UNIX chuẩn, không phải là Python cụ thể ...

+0

nếu quá trình con thoát sau khi thực hiện? – zuo

+0

@zuo Quá trình con nên 'exec' (thay thế nó bằng con để chạy) hoặc' _exit'. – ephemient

+0

cảm ơn cho câu trả lời – zuo

1

Cách truyền thống, UNIX-y để giao tiếp với các tiến trình con là mở đường ống đến đầu vào/đầu ra tiêu chuẩn của chúng và sử dụng cuộc gọi hệ thống select() để ghép các thông tin liên lạc trong quá trình cha (có sẵn trong Python thông qua ... mô-đun select).

Nếu bạn cần giết quá trình con chạy chậm, bạn chỉ có thể lưu ID tiến trình của nó (trả lại bằng gọi os.fork()) và sau đó sử dụng os.kill() để xóa khi không cần nữa. Tất nhiên, nó có lẽ sẽ sạch hơn để có thể giao tiếp với quá trình con một cách rõ ràng và yêu cầu nó để tự tắt.

4

Ephemient: mỗi đứa trẻ trong mã của bạn sẽ ở trong vòng lặp sau khi công việc của mình kết thúc. Anh ta sẽ ngã ba lần nữa. Hơn nữa, trẻ em bắt đầu khi trẻ em [] không có sản phẩm nào sẽ cố gắng chờ đợi một số anh em của chúng ở cuối vòng lặp. Cuối cùng ai đó sẽ sụp đổ. Đây là giải pháp thay thế:

import os, time 

def doTheJob(job): 
    for i in xrange(10): 
     print job, i 
     time.sleep(0.01*ord(os.urandom(1))) 
     # random.random() would be the same for each process 

jobs = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"] 
imTheFather = True 
children = [] 

for job in jobs: 
    child = os.fork() 
    if child: 
     children.append(child) 
    else: 
     imTheFather = False 
     doTheJob(job) 
     break 

# in the meanwhile 
# ps aux|grep python|grep -v grep|wc -l == 11 == 10 children + the father 

if imTheFather: 
    for child in children: 
     os.waitpid(child, 0) 
+1

Khi nhận xét trong mã nguồn của tôi cho biết, cần phải thay thế "pass" bằng "exec (job) hoặc tương tự". Nếu điều đó được thực hiện, mọi thứ sẽ hoạt động như mong đợi. Ngoài ra, bạn nên sử dụng os.exit() thay vì thiết lập imTheFather. – ephemient

+0

@ephemient Nhưng tại sao 'os._exit()' lại tốt hơn? –

+0

@AloisMahdal sử dụng để thoát khỏi quá trình con chia nhỏ http://docs.python.org/2/library/os.html#os._exit – Marconi

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