Saya belum melihat contoh yang jelas dengan kasus penggunaan untuk Pool.apply , Pool.apply_async dan Pool.map . Saya terutama menggunakan Pool.map; apa kelebihan orang lain?
Saya belum melihat contoh yang jelas dengan kasus penggunaan untuk Pool.apply , Pool.apply_async dan Pool.map . Saya terutama menggunakan Pool.map; apa kelebihan orang lain?
Jawaban:
Kembali ke masa lalu Python, untuk memanggil fungsi dengan argumen arbitrer, Anda akan menggunakan apply:
apply(f,args,kwargs)
applymasih ada di Python2.7 meskipun tidak di Python3, dan umumnya tidak digunakan lagi. Sekarang,
f(*args,**kwargs)
lebih disukai. The multiprocessing.Poolmodul mencoba untuk menyediakan antarmuka yang sama.
Pool.applyseperti Python apply, kecuali bahwa pemanggilan fungsi dilakukan dalam proses terpisah. Pool.applyblok sampai fungsi selesai.
Pool.apply_asyncjuga seperti built-in Python apply, kecuali bahwa panggilan kembali dengan segera alih-alih menunggu hasilnya. Sebuah AsyncResultobjek dikembalikan. Anda memanggil get()metode untuk mengambil hasil dari panggilan fungsi. The get()Metode blok sampai fungsi selesai. Jadi, pool.apply(func, args, kwargs)sama dengan pool.apply_async(func, args, kwargs).get().
Berbeda dengan Pool.apply, Pool.apply_asyncmetode ini juga memiliki panggilan balik yang, jika disediakan, dipanggil ketika fungsi selesai. Ini bisa digunakan alih-alih menelepon get().
Sebagai contoh:
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()
dapat menghasilkan hasil seperti
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Perhatikan, tidak seperti pool.map, urutan hasil mungkin tidak sesuai dengan urutan di mana pool.apply_asyncpanggilan dilakukan.
Jadi, jika Anda perlu menjalankan fungsi dalam proses terpisah, tetapi ingin proses saat ini untuk memblokir sampai fungsi itu kembali, gunakan Pool.apply. Seperti Pool.apply, Pool.mapmemblokir sampai hasil lengkap dikembalikan.
Jika Anda ingin Kelompok pekerja proses melakukan banyak panggilan fungsi secara tidak sinkron, gunakan Pool.apply_async. The agar hasil tidak dijamin sama dengan urutan panggilan ke Pool.apply_async.
Perhatikan juga bahwa Anda dapat memanggil sejumlah fungsi berbedaPool.apply_async (tidak semua panggilan perlu menggunakan fungsi yang sama).
Sebaliknya, Pool.mapberlaku fungsi yang sama untuk banyak argumen. Namun, tidak seperti Pool.apply_async, hasilnya dikembalikan dalam urutan yang sesuai dengan urutan argumen.
Pool.map(func,iterable)itu setara dengan Pool.map_async(func,iterable).get(). Jadi hubungan antara Pool.mapdan Pool.map_asyncmirip dengan Pool.applydan Pool.apply_async. The asyncperintah kembali segera, sedangkan non asyncperintah memblokir. The asyncperintah juga memiliki callback.
Pool.mapdan Pool.applymirip dengan memutuskan kapan akan menggunakan mapatau applydengan Python. Anda cukup menggunakan alat yang sesuai dengan pekerjaan. Memutuskan antara menggunakan asyncdan bukan asyncversi tergantung pada apakah Anda ingin panggilan untuk memblokir proses saat ini dan / atau jika Anda ingin menggunakan panggilan balik.
apply_asyncmengembalikan ApplyResultobjek. Menyebut bahwa ApplyResult's getmetode akan mengembalikan nilai kembali fungsi terkait (atau kenaikan gaji mp.TimeoutErrorjika kali-out. Panggilan) Jadi, jika Anda menempatkan ApplyResultdalam daftar memerintahkan, kemudian memanggil mereka getmetode akan mengembalikan hasil dalam urutan yang sama. Anda bisa menggunakannya pool.mapdalam situasi ini.
Tentang applyvs map:
pool.apply(f, args): fhanya dieksekusi di SALAH SATU pekerja kolam. Jadi SALAH SATU proses di kolam akan berjalan f(args).
pool.map(f, iterable): Metode ini memotong iterable ke dalam sejumlah chunk yang dikirimkan ke kumpulan proses sebagai tugas yang terpisah. Jadi, Anda memanfaatkan semua proses di kolam renang.
apply_async()8 kali? Apakah akan secara otomatis menanganinya dengan antrian?
Berikut ini adalah ikhtisar dalam format tabel untuk menunjukkan perbedaan antara Pool.apply, Pool.apply_async, Pool.mapdan Pool.map_async. Saat memilih satu, Anda harus mempertimbangkan multi-argumen, konkurensi, pemblokiran, dan pemesanan:
| 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.imapdan Pool.imap_async- versi peta dan map_async yang lebih malas.
Pool.starmap Metode, sangat mirip dengan metode peta selain itu menerima beberapa argumen.
Asyncmetode mengirimkan semua proses sekaligus dan mengambil hasilnya setelah selesai. Gunakan metode get untuk mendapatkan hasil.
Pool.map(atau Pool.apply) metode sangat mirip dengan peta bawaan Python (atau terapkan). Mereka memblokir proses utama sampai semua proses selesai dan mengembalikan hasilnya.
Disebut untuk daftar pekerjaan dalam satu waktu
results = pool.map(func, [1, 2, 3])
Hanya bisa dipanggil untuk satu pekerjaan
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Disebut untuk daftar pekerjaan dalam satu waktu
pool.map_async(func, jobs, callback=collect_result)
Hanya dapat dipanggil untuk satu pekerjaan dan mengeksekusi pekerjaan di latar belakang secara paralel
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
Merupakan varian pool.mapyang mendukung banyak argumen
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Kombinasi starmap () dan map_async () yang beriterasi iterable dari iterables dan memanggil func dengan iterables dibongkar. Mengembalikan objek hasil.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Temukan dokumentasi lengkap di sini: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"sebelumnyaapply_async_with_callback()di Windows?