मल्टीथ्रेडिंग बनाम मल्टीथ्रेडिंग बनाम एसिंसीओ इन पायथन 3


105

मैंने पाया है कि अजगर 3.4 में वहाँ बहु / सूत्रण के लिए कुछ अलग पुस्तकालयों हैं: बहु बनाम सूत्रण बनाम asyncio

लेकिन मुझे नहीं पता कि कौन सा उपयोग करना है या "अनुशंसित एक" है। क्या वे एक ही काम करते हैं, या अलग हैं? यदि हां, तो कौन सा किसके लिए उपयोग किया जाता है? मैं एक प्रोग्राम लिखना चाहता हूं जो मेरे कंप्यूटर में मल्टीकोर्स का उपयोग करता है। लेकिन मुझे नहीं पता कि मुझे कौन सी लाइब्रेरी सीखनी चाहिए।


जवाबों:


79

वे (थोड़ा) विभिन्न उद्देश्यों और / या आवश्यकताओं के लिए अभिप्रेत हैं। CPython (एक विशिष्ट, मेनलाइन पायथन कार्यान्वयन) में अभी भी वैश्विक दुभाषिया लॉक है इसलिए एक बहु-थ्रेडेड अनुप्रयोग (आजकल समानांतर प्रसंस्करण को लागू करने का एक मानक तरीका) उप-रूपी है। इसलिए multiprocessing इसे ज्यादा पसंद किया जा सकता है threading। लेकिन हर समस्या को प्रभावी रूप से [लगभग स्वतंत्र] टुकड़ों में विभाजित नहीं किया जा सकता है, इसलिए भारी इंटरप्रोसेस संचार की आवश्यकता हो सकती है। इसलिए सामान्य तौर multiprocessingपर इसे पसंद नहीं किया जा सकता है threading

asyncio(यह तकनीक न केवल पायथन में उपलब्ध है, अन्य भाषाओं और / या रूपरेखाओं में भी है, जैसे Boost.ASIO ) कई समान स्रोतों से प्रभावी रूप से I / O संचालन को प्रभावी ढंग से संभालने के लिए एक विधि है जिसे समानांतर कोड निष्पादन की आवश्यकता है। । तो यह एक विशेष कार्य के लिए सिर्फ एक समाधान है (एक अच्छा वास्तव में!), सामान्य रूप से समानांतर प्रसंस्करण के लिए नहीं।


7
यह देखते हुए कि तीनों समानता प्राप्त नहीं कर सकते हैं, वे सभी समवर्ती (गैर-अवरुद्ध) कार्यों को करने में सक्षम हैं।
सरगस

65

[शीघ्र जवाब]

टी एल; डॉ

सही विकल्प बनाना:

हम समसामयिकता के सबसे लोकप्रिय रूपों से गुजरे हैं। लेकिन सवाल बना हुआ है - कब किसे चुनना चाहिए? यह वास्तव में उपयोग के मामलों पर निर्भर करता है। अपने अनुभव (और पढ़ने) से, मैं इस छद्म कोड का पालन करता हूं:

if io_bound:
    if io_very_slow:
        print("Use Asyncio")
    else:
        print("Use Threads")
else:
    print("Multi Processing")
  • सीपीयू बाउंड => मल्टी प्रोसेसिंग
  • आई / ओ बाउंड, फास्ट आई / ओ, कनेक्शन की सीमित संख्या => मल्टी थ्रेडिंग
  • I / O बाउंड, धीमा I / O, कई कनेक्शन => Asyncio

संदर्भ


[ नोट ]:

  • यदि आपके पास एक लंबी कॉल विधि (यानी एक ऐसा तरीका है जिसमें नींद का समय या आलसी I / O शामिल है), तो सबसे अच्छा विकल्प एसिंसीओ , ट्विस्टेड या टॉर्नेडो दृष्टिकोण ( कोराउटीन तरीके) है, जो एक एकल थ्रेड के रूप में काम करता है।
  • asyncio Python3.4 और बाद में काम करता है ।
  • पाइथन 2.7 के बाद से बवंडर और ट्विस्ट तैयार हैं
  • uvloop अल्ट्रा फास्ट asyncioइवेंट लूप है ( uvloopasyncio 2-4x तेज बनाता है )।

[अद्यतन (2019)]:

  • जेप्रान्टो ( GitHub ) uvloop पर आधारित एक बहुत तेज़ पाइपलाइन HTTP सर्वर है ।

इसलिए यदि मेरे पास अनुरोध करने के लिए urls की सूची है, तो Asyncio का उपयोग करना बेहतर है ?
मिंगचाउ

1
@mingchau, हाँ, लेकिन ध्यान रखें, asyncioजब आप प्रतीक्षा योग्य कार्यों से उपयोग करते हैं, तब से उपयोग कर सकते हैं , requestपुस्तकालय एक प्रतीक्षित विधि नहीं है, इसके बजाय आप aiohttpलाइब्रेरी या async-request और इत्यादि का उपयोग कर सकते हैं
Benyamin Jafan

कृपया मल्टीथ्रेड या एसिंसीओ जाने के लिए धीमे और फास्टियो पर विस्तार करें?
qrtLs

@qrtLs जब आपके पास एक SlowIO है, तो AsyncIO बहुत मददगार और अधिक कुशल है।
बेनामिन जाफरी

1
@ पराबैंगनी I / O बाध्य का मतलब है कि आपका कार्यक्रम अपना अधिकांश समय एक धीमी डिवाइस से बात कर रहा है, जैसे नेटवर्क कनेक्शन, हार्ड ड्राइव, प्रिंटर या स्लीप टाइम वाला इवेंट लूप। इसलिए ब्लॉकिंग मोड में, आप थ्रेडिंग या एसिंसीओ के बीच चयन कर सकते हैं, और यदि आपका बाउंडिंग सेक्शन बहुत धीमा है, तो सहकारी मल्टीटास्किंग (एसिंसीओ) एक बेहतर विकल्प है (यानी संसाधन भुखमरी, डेड-लॉक्स और दौड़ की स्थिति से बचना)
बेनामिन जाफरी

8

यह मूल विचार है:

क्या यह IO -BOUND है? ---------> उपयोगasyncio

क्या यह CPU -HEAVY है? -----> का उपयोग करेंmultiprocessing

अन्य ? ----------------------> उपयोगthreading

इसलिए मूल रूप से थ्रेडिंग से तब तक चिपके रहें जब तक आपको आईओ / सीपीयू की समस्या न हो।


0

में बहु आप एक से अधिक CPU का लाभ उठाने अपनी गणना वितरित करने के लिए। चूंकि प्रत्येक CPU समानांतर में चलता है, आप प्रभावी रूप से एक साथ कई कार्यों को चलाने में सक्षम होते हैं। आप सीपीयू-बाउंड कार्यों के लिए मल्टीप्रोसेसिंग का उपयोग करना चाहेंगे । एक उदाहरण एक विशाल सूची के सभी तत्वों की राशि की गणना करने की कोशिश कर रहा होगा। यदि आपकी मशीन में 8 कोर हैं, तो आप सूची को 8 छोटी सूचियों में "काट" सकते हैं और प्रत्येक सूची के योग की गणना अलग-अलग कोर पर अलग-अलग कर सकते हैं और फिर बस उन संख्याओं को जोड़ सकते हैं। ऐसा करने से आपको ~ 8x स्पीडअप मिलेगा।

में सूत्रणआपको कई सीपीयू की आवश्यकता नहीं है। एक कार्यक्रम की कल्पना करें जो वेब पर बहुत सारे HTTP अनुरोध भेजता है। यदि आपने एकल-थ्रेडेड प्रोग्राम का उपयोग किया है, तो यह प्रत्येक अनुरोध पर निष्पादन (ब्लॉक) को रोक देगा, प्रतिक्रिया की प्रतीक्षा करेगा और फिर एक बार प्रतिक्रिया प्राप्त करने के बाद जारी रहेगा। यहाँ समस्या यह है कि आपका CPU वास्तव में काम करने के लिए किसी बाहरी सर्वर की प्रतीक्षा करते हुए काम नहीं कर रहा है; यह वास्तव में इस बीच कुछ उपयोगी काम कर सकता था! फिक्स थ्रेड्स का उपयोग करना है - आप उनमें से कई बना सकते हैं, प्रत्येक वेब से कुछ सामग्री के अनुरोध के लिए जिम्मेदार है। थ्रेड्स के बारे में अच्छी बात यह है कि, भले ही वे एक सीपीयू पर चलते हों, सीपीयू समय-समय पर एक थ्रेड के निष्पादन को "फ्रीज" करता है और दूसरे को निष्पादित करने के लिए कूदता है (इसे संदर्भ स्विचिंग कहा जाता है और यह लगातार गैर-नियतात्मक होता है अंतराल)। - थ्रेडिंग का उपयोग करें।

asyncio अनिवार्य रूप से जहां CPU नहीं बल्कि प्रोग्रामर (या वास्तव में आपके एप्लिकेशन) के रूप में फैल रहा है , यह तय करें कि संदर्भ स्विच कहां और कब होता है । Python में आप awaitअपने coroutine ( asyncकीवर्ड का उपयोग करके परिभाषित ) के निष्पादन को निलंबित करने के लिए एक कीवर्ड का उपयोग करते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.