Havuz: Uygula, uygula_async veya harita ne zaman kullanılır?


Yanıtlar:


424

Python'un eski günlerinde, rastgele bağımsız değişkenlere sahip bir işlevi çağırmak için şunları kullanırsınız apply:

apply(f,args,kwargs)

applyhala Python3'te olmasa da Python2.7'de bulunmaktadır ve genellikle artık kullanılmamaktadır. Şu günlerde,

f(*args,**kwargs)

tercih edilir. multiprocessing.PoolModüller benzer bir arayüz sağlamaya çalışır.

Pool.applyapplyişlev çağrısının ayrı bir işlemde gerçekleştirilmesi dışında Python gibidir . Pool.applyfonksiyon tamamlanana kadar engeller.

Pool.apply_asyncPython'un yerleşik olduğu gibi apply, ancak arama sonucu sonucu beklemek yerine hemen geri döner. Bir AsyncResultnesne döndürülür. Bunu diyoruz get()işlev çağrısının sonucunu almak için yöntem. get()İşlev kadar yöntemi engeller tamamlanır. Böylece, pool.apply(func, args, kwargs)eşdeğerdir pool.apply_async(func, args, kwargs).get().

Bunun aksine Pool.apply, Pool.apply_asyncyöntemin, ayrıca, işlev tamamlandığında çağrıldığında çağrılan bir geri çağrısı vardır. Bu, arama yapmak yerine kullanılabilir get().

Örneğin:

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()

gibi bir sonuç verebilir

[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]

Dikkat edin, pool.mapsonuçların sırası, pool.apply_asyncaramaların yapıldığı sıraya uygun olmayabilir .


Dolayısıyla, bir işlevi ayrı bir işlemde çalıştırmanız gerekiyorsa, ancak geçerli işlemin bu işlev dönene kadar engellenmesini istiyorsanız , kullanın Pool.apply. Gibi Pool.apply, Pool.maptam sonuç dönene kadar engeller.

İşçi Havuzu işlemlerinin birçok işlev çağrısını eşzamansız olarak gerçekleştirmesini istiyorsanız kullanın Pool.apply_async. Sipariş sonuçlarının çağrıları için aynı olması garanti edilmez Pool.apply_async.

Ayrıca, bir dizi farklı işlevi çağırabileceğinize dikkat edin Pool.apply_async(tüm aramaların aynı işlevi kullanması gerekmez).

Aksine, Pool.mapaynı işlevi birçok argümana uygular. Bununla birlikte, Pool.apply_asyncsonuçlar, argümanların sırasına karşılık gelen bir sırayla döndürülür.


11
Windows'da daha if __name__=="__main__"önce olmalı mı apply_async_with_callback()?
jfs

3
Çok teşekkürler. map_async nasıl?
Phyo Arkar Lwin

38
Multiprocessing / pool.py içine bakın ve Pool.map(func,iterable)bunun eşdeğer olduğunu göreceksiniz Pool.map_async(func,iterable).get(). Arasındaki ilişki Yani Pool.mapve Pool.map_asyncbenzer olduğunu Pool.applyve Pool.apply_async. asyncOlmayan ederken komutlar, derhal geri asynckomutları engeller. asyncKomutlar da bir geri arama var.
unutbu

7
Kullanmak arasındaki karar vermek Pool.mapve Pool.applykullanmak, karar vermek benzer mapveya applyPython. Sadece işe uyan aracı kullanın. Kullanmak arasındaki karar vermek asyncve sivil asyncversiyonunu Çağrı akım sürecini engellemek istiyorsanız bağlıdır ve / veya geri arama kullanmak istiyorsanız.
unutbu

6
@falsePockets: Evet. Her çağrı apply_asyncbir ApplyResultnesne döndürür . Bu çağrı ApplyResultbireyin get(veya zam yöntemi ilişkili işlevin dönüş değeri döndürecektir mp.TimeoutErrorçağrı süreleri aşımı.) Böylece eğer koymak ApplyResultdaha sonra arayarak, sıralı bir listedeki s getaynı sırayla sonuçları döndürür yöntemleri. pool.mapAncak bu durumda kullanabilirsiniz .
unutbu

75

applyVs ile ilgili map:

pool.apply(f, args): fhavuzun sadece bir tanesinde idam edilir. Böylece havuzdaki süreçlerden BİRİ çalışır f(args).

pool.map(f, iterable): Bu yöntem, yinelenebilir işlem havuzuna ayrı görevler olarak gönderdiği bir dizi parçaya ayırır. Böylece havuzdaki tüm işlemlerden faydalanırsınız.


4
yinelenebilir bir jeneratör ise
RustyShackleford

Hmm ... Güzel soru. Dürüst olmak gerekirse, hiç jeneratörlü havuz kullanmadım, ancak bu konu yardımcı olabilir: stackoverflow.com/questions/5318936/…
kakhkAtion

@kakhkAtion ile ilgili olarak, eğer işçilerden sadece biri işlevi yerine getirirse, geri kalan işçiler ne yapar? İşçilerin geri kalanının bir görevi yerine getirebilmesi için birden fazla kez başvurmayı çağırmam gerekir mi?
Moondra

3
Doğru. Ayrıca işçileri eşzamansız olarak öğle yemeği yemek istiyorsanız pool.apply_async'e bir göz atın. "pool_apply sonuç hazır olana kadar engeller, bu yüzden camera_appync () paralel çalışma için daha uygundur"
kakhkAtion

1
4 işlemim var, ancak apply_async()8 kez aradığımda ne olur ? Otomatik olarak bir kuyrukla başa çıkacak mı?
Saravanabalagi Ramachandran

31

İşte arasındaki farkları göstermek için bir tablo biçiminde bir bakış Pool.apply, Pool.apply_async, Pool.mapve Pool.map_async. Birini seçerken, çoklu argümanları, eşzamanlılığı, engellemeyi ve siparişi dikkate almanız gerekir:

                  | 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

Notlar:

  • Pool.imapve Pool.imap_async- map ve map_async'in daha tembel versiyonu.

  • Pool.starmap yöntemi, çok sayıda argümanın kabulünün yanı sıra harita yöntemine çok benzer.

  • Asyncyöntemleri tüm işlemleri bir kerede gönderir ve bittikten sonra sonuçları alır. Sonuçları elde etmek için get yöntemini kullanın.

  • Pool.map(veya Pool.apply) yöntemler Python yerleşik haritasına çok benzer (veya uygulayın). Tüm süreçler tamamlanana ve sonucu döndürene kadar ana süreci engellerler.

Örnekler:

harita

Bir seferde işlerin listesi için çağrılır

results = pool.map(func, [1, 2, 3])

uygulamak

Sadece bir iş için çağrılabilir

for x, y in [[1, 1], [2, 2]]:
    results.append(pool.apply(func, (x, y)))

def collect_result(result):
    results.append(result)

map_async

Bir seferde işlerin listesi için çağrılır

pool.map_async(func, jobs, callback=collect_result)

apply_async

Yalnızca bir iş için çağrılabilir ve arka planda bir işi paralel olarak yürütür

for x, y in [[1, 1], [2, 2]]:
    pool.apply_async(worker, (x, y), callback=collect_result)

starmap

pool.mapBirden fazla argümanı destekleyen bir varyantıdır

pool.starmap(func, [(1, 1), (2, 1), (3, 1)])

starmap_async

Yinelenebilir yinelemelerin üzerinden yinelenen ve paketten çıkarılan yinelenebilirler ile çağrı yapan bir starmap () ve map_async () birleşimi. Bir sonuç nesnesi döndürür.

pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)

Referans:

Belgelerin tamamını burada bulabilirsiniz: https://docs.python.org/3/library/multiprocessing.html


2
Pool.starmap () engelliyor
Alan Evangelista
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.