मैं के साथ के लिए उपयोग-मामले स्पष्ट उदाहरण नहीं देखा है Pool.apply , Pool.apply_async और Pool.map । मैं मुख्य रूप से उपयोग कर रहा हूं Pool.map
; दूसरों के फायदे क्या हैं?
मैं के साथ के लिए उपयोग-मामले स्पष्ट उदाहरण नहीं देखा है Pool.apply , Pool.apply_async और Pool.map । मैं मुख्य रूप से उपयोग कर रहा हूं Pool.map
; दूसरों के फायदे क्या हैं?
जवाबों:
पायथन के पुराने दिनों में वापस, मनमाने ढंग से तर्कों के साथ एक समारोह को बुलाने के लिए, आप उपयोग करेंगे apply
:
apply(f,args,kwargs)
apply
अभी भी Python2.7 में मौजूद है, हालांकि Python3 में नहीं है, और आमतौर पर इसका उपयोग नहीं किया जाता है। आजकल,
f(*args,**kwargs)
पसंद है। multiprocessing.Pool
मॉड्यूल एक समान इंटरफेस प्रदान करने की कोशिश करता है।
Pool.apply
पायथन की तरह है apply
, सिवाय इसके कि फ़ंक्शन कॉल एक अलग प्रक्रिया में किया जाता है। Pool.apply
फ़ंक्शन पूरा होने तक ब्लॉक करता है।
Pool.apply_async
पायथन के बिल्ट-इन की तरह भी है apply
, सिवाय इसके कि कॉल रिजल्ट के इंतजार के बजाय तुरंत लौट आए। कोई AsyncResult
वस्तु लौटा दी जाती है। आप get()
फ़ंक्शन कॉल के परिणाम को प्राप्त करने के लिए इसकी विधि कहते हैं। get()
समारोह जब तक विधि ब्लॉक पूरा हो गया है। इस प्रकार, pool.apply(func, args, kwargs)
के बराबर है pool.apply_async(func, args, kwargs).get()
।
इसके विपरीत Pool.apply
, Pool.apply_async
विधि में एक कॉलबैक भी होता है, जिसे यदि आपूर्ति की जाती है, तो फ़ंक्शन पूरा होने पर कॉल किया जाता है। इसका उपयोग कॉल करने के बजाय किया जा सकता है get()
।
उदाहरण के लिए:
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()
इस तरह के रूप में एक परिणाम मिल सकता है
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
नोटिस, इसके विपरीत pool.map
, परिणामों का क्रम उस क्रम के अनुरूप नहीं हो सकता है जिसमें pool.apply_async
कॉल किए गए थे।
इसलिए, यदि आपको एक अलग प्रक्रिया में एक फ़ंक्शन चलाने की आवश्यकता है, लेकिन उस फ़ंक्शन को वापस करने तक वर्तमान प्रक्रिया को अवरुद्ध करना चाहते हैं , तो उपयोग करें Pool.apply
। जैसे Pool.apply
, Pool.map
जब तक पूरा परिणाम वापस नहीं आता तब तक ब्लॉक करें।
यदि आप चाहते हैं कि कार्यकर्ता कई प्रक्रियाओं को असिंक्रोनस रूप से करने के लिए पूल का उपयोग करें Pool.apply_async
। आदेश परिणामों के लिए कॉल के आदेश के रूप में ही होने की गारंटी नहीं है Pool.apply_async
।
ध्यान दें कि आप कई अलग-अलग फ़ंक्शन के साथ कॉल कर सकते हैं Pool.apply_async
(सभी कॉल को एक ही फ़ंक्शन का उपयोग करने की आवश्यकता नहीं है)।
इसके विपरीत, Pool.map
एक ही फ़ंक्शन कई तर्कों पर लागू होता है। हालांकि, इसके विपरीत Pool.apply_async
, परिणाम तर्कों के क्रम के अनुसार एक क्रम में वापस आ जाते हैं।
Pool.map(func,iterable)
यह बराबर है Pool.map_async(func,iterable).get()
। तो बीच के रिश्ते Pool.map
और Pool.map_async
के समान है Pool.apply
और Pool.apply_async
। async
जबकि गैर आदेश, तुरंत लौट async
आदेशों को ब्लॉक। async
आदेशों भी एक कॉलबैक है।
Pool.map
और तय करना के Pool.apply
समान है कि कब उपयोग करना है map
या apply
पायथन में है। आप बस उस टूल का उपयोग करते हैं जो काम को फिट करता है। async
और गैर- async
संस्करण का उपयोग करने के बीच निर्णय लेना इस बात पर निर्भर करता है कि क्या आप कॉल को वर्तमान प्रक्रिया को ब्लॉक करना चाहते हैं और / या यदि आप कॉलबैक का उपयोग करना चाहते हैं।
apply_async
एक ApplyResult
वस्तु को वापस करने के लिए । कॉलिंग कि ApplyResult
की get
विधि संबद्ध फ़ंक्शन द्वारा दिया गया मूल्य (या बढ़ाने वापस आ जाएगी mp.TimeoutError
, तो कॉल समय बाहर।) तो अगर आप डाल ApplyResult
एक आदेश दिया सूची में, तो उनके फोन करने get
के तरीकों उसी क्रम में परिणाम देगा। आप pool.map
हालांकि इस स्थिति में उपयोग कर सकते हैं ।
apply
बनाम के बारे में map
:
pool.apply(f, args)
: f
केवल पूल के श्रमिकों में से एक में निष्पादित किया जाता है। तो पूल में से एक प्रक्रिया चलेगी f(args)
।
pool.map(f, iterable)
: यह विधि पुनरावृत्ति को कई संख्या में काट देती है जिसे यह प्रक्रिया पूल में अलग-अलग कार्यों के रूप में जमा करता है। तो आप पूल में सभी प्रक्रियाओं का लाभ उठाते हैं।
apply_async()
8 बार कॉल किया जाता है? क्या यह स्वचालित रूप से एक कतार के साथ इसे संभाल लेगा?
यहाँ आदेश के बीच मतभेदों को दिखाने के लिए एक तालिका प्रारूप में एक सिंहावलोकन है Pool.apply
, Pool.apply_async
, Pool.map
और Pool.map_async
। एक का चयन करते समय, आपको मल्टी-आर्ग, कंसीडर, ब्लॉकिंग और ऑर्डर को ध्यान में रखना होगा:
| 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.imap
और Pool.imap_async
- नक्शा और map_async का lazier संस्करण।
Pool.starmap
विधि, कई तर्कों की स्वीकृति के अलावा मानचित्र विधि के समान है।
Async
विधियाँ एक बार में सभी प्रक्रियाएँ प्रस्तुत करती हैं और एक बार समाप्त होने के बाद परिणाम निकालती हैं। परिणाम प्राप्त करने के लिए विधि का उपयोग करें।
Pool.map
(या Pool.apply
) विधियाँ बहुत हद तक बिल्ट-इन मैप (या लागू) के समान हैं। वे सभी प्रक्रियाओं को पूरा करने और परिणाम को वापस करने तक मुख्य प्रक्रिया को अवरुद्ध करते हैं।
एक समय में नौकरियों की सूची के लिए कहा जाता है
results = pool.map(func, [1, 2, 3])
केवल एक काम के लिए बुलाया जा सकता है
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
एक समय में नौकरियों की सूची के लिए कहा जाता है
pool.map_async(func, jobs, callback=collect_result)
केवल एक नौकरी के लिए बुलाया जा सकता है और समानांतर में पृष्ठभूमि में नौकरी निष्पादित करता है
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
एक प्रकार है pool.map
जो कई तर्कों का समर्थन करता है
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Starmap () और map_async () का एक संयोजन जो पुनरावृत्तियों के पुनरावृत्तियों पर पुनरावृत्त करता है और इसे पुनरावृत्त किए गए पुनरावृत्तियों के साथ कॉल करता है। परिणाम वस्तु देता है।
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
यहां पूर्ण प्रलेखन ढूंढें: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
पहले होना चाहिएapply_async_with_callback()
?