मैं के साथ के लिए उपयोग-मामले स्पष्ट उदाहरण नहीं देखा है 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()?