เมื่อใดที่เราควรเรียกว่า multiprocessing.Pool.join?


96

ฉันใช้ 'multiprocess.Pool.imap_unordered' ดังต่อไปนี้

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

ฉันต้องโทรpool.closeหรือpool.joinหลังจากวนซ้ำ?


ฉันมักเรียกpool.join()แล้วpool.close()เมื่อฉันได้เริ่มต้นทั้งหมดของหัวข้อสระว่ายน้ำ แต่ฉันไม่ได้พยายามใช้pool.imap_unordered()เป็น iterable
Bamcclur

8
จุดโทรเข้าร่วมหรือปิดคืออะไร? ฉันไม่ได้โทรหาพวกเขาและดูเหมือนว่ารหัสของฉันจะใช้งานได้ดี อย่างไรก็ตามฉันกังวลว่าการไม่เรียกสิ่งเหล่านี้จะส่งผลให้เกิดกระบวนการซอมบี้หรือสิ่งที่ละเอียดอ่อนอื่น ๆ
hch

คำตอบ:


113

ไม่คุณไม่ทำ แต่อาจเป็นความคิดที่ดีหากคุณจะไม่ใช้สระว่ายน้ำอีกต่อไป

เหตุผลในการโทรpool.closeหรือpool.joinพูดได้ดีโดย Tim Peters ในโพสต์ SO นี้ :

สำหรับ Pool.close () คุณควรเรียกสิ่งนั้นว่าเมื่อไรและต่อเมื่อคุณจะไม่ส่งงานไปยังอินสแตนซ์ Pool อีก โดยทั่วไปแล้ว Pool.close () จะถูกเรียกเมื่อส่วนที่ขนานกันได้ของโปรแกรมหลักของคุณเสร็จสิ้น จากนั้นกระบวนการของผู้ปฏิบัติงานจะสิ้นสุดลงเมื่องานทั้งหมดที่ได้รับมอบหมายเสร็จสิ้นแล้ว

นอกจากนี้ยังควรเรียก Pool.join () เพื่อรอให้กระบวนการของผู้ปฏิบัติงานยุติลง ด้วยเหตุผลอื่น ๆ มักไม่มีวิธีที่ดีในการรายงานข้อยกเว้นในโค้ดคู่ขนาน (ข้อยกเว้นเกิดขึ้นในบริบทที่เกี่ยวข้องกับสิ่งที่โปรแกรมหลักของคุณกำลังทำอย่างคลุมเครือเท่านั้น) และ Pool.join () มีจุดซิงโครไนซ์ที่สามารถรายงานข้อยกเว้นบางประการที่เกิดขึ้น ในกระบวนการทำงานที่คุณไม่เคยเห็น


9
โทรหากันก่อนดีกว่าไหม
RSHAP

9
ดูเหมือนว่าผู้คนจะชอบเรียกpool.close()ครั้งแรกและpool.join()ครั้งที่สอง สิ่งนี้ช่วยให้คุณสามารถเพิ่มงานระหว่างpool.close()และpool.join()ที่ไม่จำเป็นต้องรอให้พูลทำงานเสร็จสิ้น
Bamcclur

34
เพียงเพื่อเพิ่มความคิดเห็นของ @ Bamcclur - ไม่ใช่แค่ควรโทรหาpool.close()ก่อนเท่านั้น แต่เป็นสิ่งที่จำเป็นจริงๆ จากเอกสาร : หนึ่งต้องโทรclose()หรือก่อนที่จะใช้terminate() join()
Bogd

4
@ บ็อก แต่ทำไมถึงบังคับ? คุณช่วยตอบคำถามนี้ได้ไหม
agdhruv

คำตอบสำหรับคำถาม agdhruvs จะยอดเยี่ยมมาก!
แส้

44

ฉันมีปัญหาหน่วยความจำเช่นเดียวกับการใช้หน่วยความจำเพิ่มขึ้นเรื่อย ๆ ด้วยการประมวลผลหลายขั้นตอนของ Pythonเมื่อฉันไม่ได้ใช้pool.close()และpool.join()เมื่อใช้pool.map()กับฟังก์ชันที่คำนวณระยะทาง Levenshtein ฟังก์ชั่นนี้ทำงานได้ดี แต่ไม่ได้รวบรวมขยะอย่างถูกต้องบนเครื่อง Win7 64 และการใช้งานหน่วยความจำยังคงเพิ่มขึ้นอย่างควบคุมไม่ได้ทุกครั้งที่เรียกใช้ฟังก์ชันจนกว่าระบบปฏิบัติการทั้งหมดจะหยุดทำงาน นี่คือรหัสที่แก้ไขการรั่วไหล:

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

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

หลังจากปิดและเข้าร่วมพูลหน่วยความจำรั่วก็หายไป


1
ฉันได้รับERROR: Terminated with signal 15ก่อนที่ฉันจะเพิ่มรหัสล้างข้อมูลpool.close();pool.join();แต่หลังจากเพิ่มรหัสการล้างข้อมูลนั้นฉันไม่ได้รับข้อความคอนโซล ดังนั้นฉันจึงสงสัยอย่างน้อยในเวอร์ชันของฉัน python 2.7 จาก C7 ว่าสระว่ายน้ำอาจไม่ได้ทำความสะอาดอย่างแน่นอน
Trevor Boyd Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.