Kapan kita harus memanggil multiprocessing.Pool.join?

96

Saya menggunakan 'multiprocess.Pool.imap_unordered' sebagai berikut

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

Apakah saya perlu menelepon pool.closeatau pool.joinsetelah loop for?

hch
sumber
Saya biasanya memanggil pool.join()kemudian pool.close()setelah saya sudah mulai semua benang kolam renang, tapi saya belum mencoba menggunakan pool.imap_unordered()sebagai iterable.
Bamcclur
8
apa gunanya menelepon gabung atau tutup? Saya tidak menelepon mereka dan kode saya tampaknya berfungsi dengan baik. Namun, saya khawatir bahwa tidak memanggil itu akan mengakibatkan proses zombie atau hal-hal halus lainnya.
hch

Jawaban:

113

Tidak, tidak, tapi mungkin ide yang bagus jika Anda tidak akan menggunakan kolam lagi.

Alasan menelepon pool.closeatau pool.joindikatakan baik oleh Tim Peters dalam posting SO ini :

Mengenai Pool.close (), Anda harus memanggilnya jika - dan hanya jika - Anda tidak akan pernah mengirimkan lebih banyak pekerjaan ke instance Pool. Jadi Pool.close () biasanya dipanggil ketika bagian program utama Anda yang dapat diparalelkan telah selesai. Kemudian proses pekerja akan berhenti ketika semua pekerjaan yang telah ditugaskan telah selesai.

Ini juga merupakan praktik yang sangat baik untuk memanggil Pool.join () untuk menunggu proses pekerja berhenti. Di antara alasan lain, seringkali tidak ada cara yang baik untuk melaporkan pengecualian dalam kode paralel (pengecualian terjadi dalam konteks yang hanya terkait secara samar dengan apa yang dilakukan program utama Anda), dan Pool.join () menyediakan titik sinkronisasi yang dapat melaporkan beberapa pengecualian yang terjadi dalam proses pekerja yang sebelumnya tidak akan pernah Anda lihat.

Bamcclur
sumber
9
apakah lebih baik menelepon yang satu sebelum yang lain?
RSHAP
9
Sepertinya orang suka menelepon pool.close()pertama dan pool.join()kedua. Ini memungkinkan Anda untuk menambahkan pekerjaan antara pool.close()dan pool.join()yang tidak perlu menunggu pool selesai dieksekusi.
Bamcclur
34
Sekadar menambah komentar @ Bamcclur - bukan hanya menelepon pool.close()dulu, tapi sebenarnya wajib. Dari dokumen : Seseorang harus menelepon close()atau terminate()sebelum menggunakan join().
Bogd
4
@ Bogd Tapi kenapa itu wajib? Bisakah Anda menjawab pertanyaan ini ?
agdhruv
Jawaban atas pertanyaan agdhruvs pasti luar biasa!
Cambuk
44

Saya memiliki masalah memori yang sama karena penggunaan memori terus berkembang dengan multiprocessing.pool Python ketika saya tidak menggunakan pool.close()dan pool.join()saat menggunakan pool.map()dengan fungsi yang menghitung jarak Levenshtein. Fungsi ini bekerja dengan baik, tetapi sampah tidak dikumpulkan dengan benar pada mesin Win7 64, dan penggunaan memori terus tumbuh di luar kendali setiap kali fungsi dipanggil hingga seluruh sistem operasi mati. Inilah kode yang memperbaiki kebocoran:

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

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

Setelah menutup dan bergabung dengan kolam, kebocoran memori hilang.

Odiseus Ithaca
sumber
1
Saya mendapatkan ERROR: Terminated with signal 15sebelum saya menambahkan kode pembersihan pool.close();pool.join();tetapi setelah menambahkan kode pembersihan itu saya tidak mendapatkan pesan konsol. jadi saya curiga setidaknya pada versi saya, python 2.7 dari C7, bahwa kolam itu mungkin entah bagaimana tidak membersihkan dengan tepat.
Trevor Boyd Smith