Khi nào chúng ta nên gọi multiprocessing.Pool.join?


96

Tôi đang sử dụng 'multiprocess.Pool.imap_unordered' như sau

from multiprocessing import Pool
pool = Pool()
for mapped_result in pool.imap_unordered(mapping_func, args_iter):
    do some additional processing on mapped_result

Tôi có cần gọi pool.closehoặc pool.joinsau vòng lặp for không?


Tôi thường gọi pool.join()sau đó pool.close()khi tôi đã bắt đầu tất cả các luồng hồ bơi, nhưng tôi chưa thử sử dụng pool.imap_unordered()như một tệp có thể lặp lại.
Bamcclur

8
điểm của việc gọi tham gia hoặc đóng là gì? Tôi đã không gọi cho họ và mã của tôi dường như đang hoạt động tốt. Tuy nhiên, tôi lo ngại rằng việc không gọi những thứ đó sẽ dẫn đến các quá trình zombie hoặc những thứ tinh vi khác.
hch

Câu trả lời:


113

Không, bạn không cần, nhưng có lẽ là một ý kiến ​​hay nếu bạn không sử dụng hồ bơi nữa.

Lý do kêu gọi pool.closehoặc pool.joinđược Tim Peters nói rõ trong bài đăng SO này :

Đối với Pool.close (), bạn nên gọi nó khi - và chỉ khi - bạn sẽ không bao giờ gửi thêm công việc cho cá thể Pool. Vì vậy, Pool.close () thường được gọi khi phần có thể song song hóa của chương trình chính của bạn kết thúc. Sau đó, các quy trình công nhân sẽ kết thúc khi tất cả công việc được giao đã hoàn thành.

Cách thực hành tuyệt vời là gọi Pool.join () để đợi các quy trình worker kết thúc. Trong số các lý do khác, thường không có cách nào tốt để báo cáo các ngoại lệ trong mã song song (các ngoại lệ xảy ra trong ngữ cảnh chỉ liên quan mơ hồ đến những gì chương trình chính của bạn đang làm) và Pool.join () cung cấp một điểm đồng bộ hóa có thể báo cáo một số ngoại lệ đã xảy ra trong các quy trình công nhân mà bạn sẽ không bao giờ thấy.


9
tốt hơn là gọi cái này trước cái kia?
RSHAP

9
Có vẻ như mọi người thích gọi pool.close()thứ nhất và pool.join()thứ hai. Điều này cho phép bạn thêm công việc giữa pool.close()pool.join()mà không cần phải đợi nhóm hoàn thành thực thi.
Bamcclur

34
Chỉ để thêm vào nhận xét của @ Bamcclur - không chỉ là một ý kiến ​​hay khi gọi pool.close()trước, nó thực sự là bắt buộc. Từ tài liệu : Người ta phải gọi close()hoặc terminate()trước khi sử dụng join().
Bogd

4
@Bogd Nhưng tại sao nó lại bắt buộc? Bạn có thể trả lời câu hỏi này được không?
agdhruv

Một câu trả lời cho câu hỏi agdhruvs sẽ thật tuyệt vời!
Roi

44

Tôi đã gặp vấn đề về bộ nhớ tương tự như việc sử dụng Bộ nhớ tiếp tục tăng với multiprocessing.pool của Python khi tôi không sử dụng pool.close()pool.join()khi sử dụng pool.map()với một hàm tính toán khoảng cách Levenshtein. Chức năng hoạt động tốt, nhưng không được thu gom rác đúng cách trên máy Win7 64 và việc sử dụng bộ nhớ tiếp tục tăng ngoài tầm kiểm soát mỗi khi chức năng này được gọi cho đến khi nó gỡ toàn bộ hệ điều hành. Đây là mã đã sửa lỗi rò rỉ:

stringList = []
for possible_string in stringArray:
    stringList.append((searchString,possible_string))

pool = Pool(5)
results = pool.map(myLevenshteinFunction, stringList)
pool.close()
pool.join()

Sau khi đóng và tham gia nhóm, lỗi rò rỉ bộ nhớ đã biến mất.


1
tôi đã nhận được ERROR: Terminated with signal 15trước khi thêm mã dọn dẹp pool.close();pool.join();nhưng sau khi thêm mã dọn dẹp đó, tôi không nhận được thông báo trên bảng điều khiển. vì vậy tôi nghi ngờ ít nhất trên phiên bản của tôi, python 2.7 từ C7, rằng hồ bơi có thể bằng cách nào đó không được dọn dẹp chính xác.
Trevor Boyd Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.