2011-12-16 34 views

Trả lời

275

Trở lại trong những ngày cũ của Python, để gọi một hàm với đối số tùy ý, bạn sẽ sử dụng apply:

apply(f,args,kwargs) 

apply vẫn còn tồn tại trong Python2.7 mặc dù không phải trong Python3, và thường không được sử dụng nữa . Ngày nay,

f(*args,**kwargs) 

được ưu tiên. Các mô-đun multiprocessing.Pool cố gắng cung cấp một giao diện tương tự.

Pool.apply giống như Python apply, ngoại trừ việc gọi hàm được thực hiện trong một quy trình riêng biệt. Pool.apply khối cho đến khi chức năng được hoàn thành.

Pool.apply_async cũng giống như tích hợp sẵn của Python apply, ngoại trừ việc cuộc gọi trả về ngay lập tức thay vì chờ kết quả. Một đối tượng ApplyResult được trả về. Bạn gọi phương thức get() để truy xuất kết quả của cuộc gọi hàm. Các khối phương thức get() cho đến khi chức năng được hoàn thành. Do đó, pool.apply(func, args, kwargs) tương đương với pool.apply_async(func, args, kwargs).get().

Ngược lại với Pool.apply, phương pháp Pool.apply_async cũng có gọi lại, nếu được cung cấp, được gọi khi chức năng hoàn tất. Điều này có thể được sử dụng thay vì gọi số get().

Ví dụ:

import multiprocessing as mp 
import time 

def foo_pool(x): 
    time.sleep(2) 
    return x*x 

result_list = [] 
def log_result(result): 
    # This is called whenever foo_pool(i) returns a result. 
    # result_list is modified only by the main process, not the pool workers. 
    result_list.append(result) 

def apply_async_with_callback(): 
    pool = mp.Pool() 
    for i in range(10): 
     pool.apply_async(foo_pool, args = (i,), callback = log_result) 
    pool.close() 
    pool.join() 
    print(result_list) 

if __name__ == '__main__': 
    apply_async_with_callback() 

có thể mang lại một kết quả như

[1, 0, 4, 9, 25, 16, 49, 36, 81, 64] 

Chú ý, không giống như pool.map, thứ tự của các kết quả có thể không tương ứng với thứ tự mà các pool.apply_async cuộc gọi đã được thực hiện .


Vì vậy, nếu bạn cần phải chạy một hàm trong một quá trình riêng biệt, nhưng muốn quá trình hiện tại để khối cho đến khi trở về chức năng, sử dụng Pool.apply. Giống như Pool.apply, Pool.map khối cho đến khi kết quả hoàn tất được trả lại.

Nếu bạn muốn Nhóm công việc của quy trình thực hiện nhiều cuộc gọi chức năng không đồng bộ, hãy sử dụng Pool.apply_async. Yêu cầu của kết quả không được đảm bảo giống như thứ tự của các cuộc gọi đến Pool.apply_async.

Cũng lưu ý rằng bạn có thể gọi một số các chức năng khác nhau với Pool.apply_async (không phải tất cả các cuộc gọi đều cần sử dụng cùng chức năng).

Ngược lại, Pool.map áp dụng cùng chức năng cho nhiều đối số. Tuy nhiên, không giống như Pool.apply_async, kết quả được trả về theo thứ tự tương ứng với thứ tự của các đối số.

+6

Nếu có 'if __name __ ==" __ chính __ "' trước 'apply_async_with_callback()' trên Windows? – jfs

+1

Có, cảm ơn lời nhắc. – unutbu

+1

Cảm ơn rất nhiều. làm thế nào về map_async? –

47

Về apply vs map:

pool.apply(f, args): f chỉ được thực hiện tại một trong những công nhân của hồ bơi. Vì vậy, MỘT trong các quy trình trong hồ bơi sẽ chạy f(args).

pool.map(f, iterable): Phương pháp này cho phép lặp lại thành một số đoạn mà nó gửi đến nhóm xử lý dưới dạng các tác vụ riêng biệt. Vì vậy, bạn tận dụng tất cả các quy trình trong hồ bơi.

+0

nếu máy lặp lại là máy phát điện –

+0

Hmm ... Câu hỏi hay. Thành thật mà nói tôi chưa bao giờ sử dụng hồ bơi với máy phát điện, nhưng thread này có thể hữu ích: https://stackoverflow.com/questions/5318936/python-multiprocessing-pool-lazy-iteration – kakhkAtion

+0

@kakhkAtion Về việc áp dụng, nếu chỉ có một của những người lao động thực thi chức năng, những người làm công việc còn lại làm gì? Tôi có phải gọi áp dụng nhiều lần để phần còn lại của công nhân thực hiện một nhiệm vụ không? – Moondra

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