Apakah ada kelas Pool untuk thread pekerja , mirip dengan kelas Pool modul multiprosesor ?
Saya suka misalnya cara mudah untuk memparalelkan fungsi peta
def long_running_func(p):
c_func_no_gil(p)
p = multiprocessing.Pool(4)
xs = p.map(long_running_func, range(100))
namun saya ingin melakukannya tanpa overhead untuk menciptakan proses baru.
Saya tahu tentang GIL. Namun, dalam usecase saya, fungsi tersebut akan menjadi fungsi C terikat IO di mana pembungkus python akan melepaskan GIL sebelum pemanggilan fungsi yang sebenarnya.
Apakah saya harus menulis kolam threading sendiri?
from multiprocessing.pool import ThreadPool
.I know about the GIL. However, in my usecase, the function will be an IO-bound C function for which the python wrapper will release the GIL before the actual function call.
?Jawaban:
Saya baru tahu bahwa sebenarnya adalah antarmuka Renang benang berbasis di
multiprocessing
modul, namun tersembunyi agak dan tidak didokumentasikan dengan baik.Itu dapat diimpor melalui
Ini diimplementasikan menggunakan kelas Proses dummy yang membungkus thread python. Kelas Proses berbasis utas ini dapat ditemukan di
multiprocessing.dummy
mana disebutkan secara singkat dalam dokumen . Modul dummy ini seharusnya menyediakan seluruh antarmuka multi-pemrosesan berdasarkan utas.sumber
multiprocessing.dummy.Pool
/multiprocessing.pool.ThreadPool
adalah hal yang sama, dan keduanya kolam utas. Mereka meniru antarmuka dari kumpulan proses, tetapi mereka diimplementasikan sepenuhnya dalam hal threading. Baca ulang dokumen, Anda mendapatkannya mundur.multiprocessing.dummy
mereplikasi APImultiprocessing
tetapi tidak lebih dari pembungkusthreading
modul."multiprocessing
secara umum adalah tentang proses, tetapi untuk memungkinkan peralihan antara proses dan utas, mereka (kebanyakan) mereplikasimultiprocessing
APImultiprocessing.dummy
, tetapi didukung dengan utas, bukan proses. Tujuannya adalah agar Andaimport multiprocessing.dummy as multiprocessing
dapat mengubah kode berbasis proses menjadi berbasis thread.Di Python 3 Anda bisa menggunakan
concurrent.futures.ThreadPoolExecutor
, yaitu:Lihat dokumen untuk info lebih lanjut dan contoh.
sumber
sudo pip install futures
ThreadPoolExecutor
danmultiprocessing.dummy.Pool
?Ya, dan tampaknya memiliki (kurang lebih) API yang sama.
sumber
ThreadPool
berbedaPool
. Impor yang benar adalahfrom multiprocessing.pool import ThreadPool
.Untuk sesuatu yang sangat sederhana dan ringan (sedikit dimodifikasi dari sini ):
Untuk mendukung panggilan balik pada penyelesaian tugas, Anda bisa menambahkan panggilan balik ke tugas tuple.
sumber
Queue.get()
memblokir) sampai program berakhir, setelah itu mereka dihentikan secara otomatis.Queue.join()
akan benar-benar bergabung dengan antrian tugas, bukan utas pekerja. Jadi, ketika antrian kosong,wait_completion
pengembalian, program berakhir, dan utas menuai oleh OS.pool.wait_completion()
kembali. Hasilnya adalah bahwa utas terus membangun.Hai untuk menggunakan kolam utas dengan Python Anda dapat menggunakan perpustakaan ini:
dan kemudian untuk digunakan, perpustakaan ini melakukan seperti itu:
Utas adalah jumlah utas yang Anda inginkan dan tugas adalah daftar tugas yang sebagian besar dipetakan ke layanan.
sumber
.close()
dan.join()
panggilan dan yang menyebabkan.map()
untuk menyelesaikan sebelum semua utas selesai. Hanya sebuah peringatan.Inilah hasil akhirnya saya gunakan. Ini adalah versi modifikasi dari kelas oleh dgorissen di atas.
Mengajukan:
threadpool.py
Untuk menggunakan kolam renang
sumber
#!/usr/bin/python3
)for i, d in enumerate(delays):
lalu mengabaikani
nilainya?i
selama menjalankan.create_task
disana? Untuk apa ini?Biaya tambahan untuk menciptakan proses baru sangat minim, terutama ketika hanya 4 dari mereka. Saya ragu ini adalah hot spot kinerja aplikasi Anda. Sederhanakan, optimalkan ke mana Anda harus pergi dan ke mana profiling menunjukkan hasil.
sumber
Tidak ada kolam berbasis benang yang dibangun. Namun, bisa sangat cepat untuk mengimplementasikan antrian produsen / konsumen dengan
Queue
kelas.Dari: https://docs.python.org/2/library/queue.html
sumber
concurrent.futures
modul.from multiprocessing.pool import ThreadPool
cara lain dapat menambahkan proses ke kumpulan antrian
sumber