Tôi chưa thấy các ví dụ rõ ràng với các trường hợp sử dụng cho Pool.apply , Pool.apply_async và Pool.map . Tôi chủ yếu sử dụng Pool.map
; những lợi thế của người khác là gì?
Tôi chưa thấy các ví dụ rõ ràng với các trường hợp sử dụng cho Pool.apply , Pool.apply_async và Pool.map . Tôi chủ yếu sử dụng Pool.map
; những lợi thế của người khác là gì?
Câu trả lời:
Quay lại thời kỳ cũ của Python, để gọi một hàm với các đối số tùy ý, bạn sẽ sử dụng apply
:
apply(f,args,kwargs)
apply
vẫn tồn tại trong Python2.7 mặc dù không có trong Python3 và thường không được sử dụng nữa. Ngày nay,
f(*args,**kwargs)
được ưa thích. Các multiprocessing.Pool
mô-đun 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. 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 AsyncResult
đối tượng được trả lại. Bạn gọi get()
phương thức của nó để lấy kết quả của hàm gọi. Các get()
phương thức chặn cho đến khi chức năng được hoàn thành. Như vậy, pool.apply(func, args, kwargs)
tương đương với pool.apply_async(func, args, kwargs).get()
.
Ngược lại Pool.apply
, Pool.apply_async
phương thức cũng có một cuộc gọi lại, nếu được cung cấp, được gọi khi hàm hoàn thành. Điều này có thể được sử dụng thay vì gọi 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]
Lưu ý, 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 chạy một hàm trong một quy trình riêng biệt, nhưng muốn quy trình hiện tại bị chặn cho đến khi chức năng đó trở lại, hãy sử dụng Pool.apply
. Giống như Pool.apply
, Pool.map
khối cho đến khi kết quả hoàn thành được trả về.
Nếu bạn muốn nhóm quy trình worker thực hiện nhiều lệnh gọi không đồng bộ, hãy sử dụng Pool.apply_async
. Thứ tự của các 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ố chức năng khác nhauPool.apply_async
(không phải tất cả các cuộc gọi đều cần sử dụng cùng một 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
, các kết quả được trả về theo thứ tự tương ứng với thứ tự của các đối số.
Pool.map(func,iterable)
tương đương với Pool.map_async(func,iterable).get()
. Vì vậy, mối quan hệ giữa Pool.map
và Pool.map_async
tương tự như Pool.apply
và Pool.apply_async
. Các async
lệnh trả về ngay lập tức, trong khi khối không async
lệnh. Các async
lệnh cũng có một cuộc gọi lại.
Pool.map
và Pool.apply
tương tự như quyết định khi nào nên sử dụng map
hoặc apply
trong Python. Bạn chỉ cần sử dụng công cụ phù hợp với công việc. Quyết định giữa việc sử dụng phiên bản async
và không async
phiên bản tùy thuộc vào việc bạn có muốn cuộc gọi chặn quy trình hiện tại và / hoặc nếu bạn muốn sử dụng cuộc gọi lại.
apply_async
trả về một ApplyResult
đối tượng. Gọi đó ApplyResult
là get
phương pháp sẽ trở lại giá trị trả về các chức năng liên quan (hoặc tăng lương mp.TimeoutError
nếu cuộc gọi lần-out.) Vì vậy, nếu bạn đặt các ApplyResult
s trong một danh sách đặt hàng, sau đó kêu gọi họ get
phương pháp này sẽ trả lại kết quả theo thứ tự. Bạn chỉ có thể sử dụng pool.map
trong tình huống này.
Về apply
vs map
:
pool.apply(f, args)
: f
chỉ được thực hiện trong MỘT trong số các công nhân của nhóm. Vì vậy, MỘT trong các quy trình trong nhóm sẽ chạy f(args)
.
pool.map(f, iterable)
: Phương thức này chia iterable thành một số khối mà nó gửi đến nhóm quy trình 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 nhóm.
apply_async()
8 lần? Nó sẽ tự động xử lý nó với một hàng đợi?
Dưới đây là một cái nhìn tổng quan trong một định dạng bảng để hiển thị sự khác nhau giữa Pool.apply
, Pool.apply_async
, Pool.map
và Pool.map_async
. Khi chọn một, bạn phải đưa nhiều đối số, đồng thời, chặn và đặt hàng vào tài khoản:
| Multi-args Concurrence Blocking Ordered-results
---------------------------------------------------------------------
Pool.map | no yes yes yes
Pool.map_async | no yes no yes
Pool.apply | yes no yes no
Pool.apply_async | yes yes no no
Pool.starmap | yes yes yes yes
Pool.starmap_async| yes yes no no
Pool.imap
và Pool.imap_async
- phiên bản lười hơn của bản đồ và map_async.
Pool.starmap
phương thức, rất giống với phương thức ánh xạ bên cạnh việc chấp nhận nhiều đối số.
Async
phương thức gửi tất cả các quy trình cùng một lúc và lấy kết quả sau khi hoàn thành. Sử dụng phương pháp get để có được kết quả.
Pool.map
(hoặc Pool.apply
) các phương thức rất giống với bản đồ dựng sẵn của Python (hoặc áp dụng). Họ chặn quy trình chính cho đến khi tất cả các quy trình hoàn thành và trả về kết quả.
Được gọi cho một danh sách các công việc trong một lần
results = pool.map(func, [1, 2, 3])
Chỉ có thể được gọi cho một công việc
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Được gọi cho một danh sách các công việc trong một lần
pool.map_async(func, jobs, callback=collect_result)
Chỉ có thể được gọi cho một công việc và thực hiện một công việc trong nền song song
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
Là một biến thể trong pool.map
đó hỗ trợ nhiều đối số
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Một sự kết hợp của starmap () và map_async () lặp đi lặp lại qua các lần lặp của các lần lặp và gọi func với các lần lặp được giải nén. Trả về một đối tượng kết quả.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Tìm tài liệu đầy đủ tại đây: https://docs.python.org/3/l Library / multiprocessing.html
if __name__=="__main__"
trướcapply_async_with_callback()
trên Windows?