2010-04-01 24 views
12

मेरे पास एक ऐसा फ़ंक्शन है जो साइड-इफेक्ट मुक्त है। मैं इसे एक सरणी में प्रत्येक तत्व के लिए चलाने के लिए और सभी परिणामों के साथ एक सरणी वापस करना चाहते हैं।क्या कोई मल्टीथ्रेडेड मानचित्र() फ़ंक्शन है?

क्या पाइथन के पास सभी मूल्यों को उत्पन्न करने के लिए कुछ है?

+0

क्या आपका नक्शा मानचित्र के रूप में कम है? क्या आप इनपुट और आउटपुट पंक्ति का उदाहरण दे सकते हैं? – Simon

+0

नहीं, मेरा मतलब नक्शा कम नहीं है। चूंकि मैं चाहता हूं कि प्रत्येक व्यक्तिगत फ़ंक्शन से सभी डेटा लौटाए। यह सिर्फ इतना है कि प्रत्येक मूल्य को एक-दूसरे से स्वतंत्र रूप से गणना की जा सकती है। हालांकि, मुझे लगता है कि मुझे सेट का अधिकतम भाग चाहिए, शायद मैं नक्शा का उपयोग यहां कम कर सकता हूं ... – Sandro

+0

नक्शा() आप जो भी कहते हैं, वह स्वतंत्र रूप से प्रत्येक तत्व पर काम करेगा (नीचे वर्णित जीआईएल चेतावनी के साथ) –

उत्तर

16

बहु से Pool.map समारोह का प्रयास करें:

http://docs.python.org/library/multiprocessing.html#using-a-pool-of-workers

यह प्रति-se थ्रेड नहीं कर रहा है, लेकिन वह वास्तव में अच्छा है के बाद से बहु सूत्रण गंभीर रूप से Gil द्वारा पायथन में अपंग है।

+0

बहुत अच्छा, आखिरी पंक्ति ने मुझे बेच दिया। मैंने पहले इस मल्टीप्रोसेसिंग लाइब्रेरी को देखा लेकिन मैंने सोचा कि यह मेरी जरूरतों के लिए बहुत भारी वजन था। मुझे लगता है कि अब मैं प्रकाश देखता हूं :) धन्यवाद। – Sandro

+0

क्या यह उत्तर मल्टीथ्रेडिंग/जीआईएल के संबंध में अद्यतित/अभी भी प्रासंगिक है? – Moberg

+0

हां, "गंभीर" के कुछ मूल्यों के लिए।"मुझे लगता है कि यह राय की बात है कि यह कितना बुरा है, लेकिन मैं अभी भी लिनक्स पर कई प्रक्रियाओं को पसंद करता हूं जहां प्रक्रियाएं बहुत भारी नहीं होतीं। – samtregar

2

आप मल्टीप्रोसेसिंग पायथन पैकेज (http://docs.python.org/library/multiprocessing.html) का उपयोग कर सकते हैं। क्लाउड पायथन पैकेज, PiCloud (http://www.picloud.com) से उपलब्ध है, एक मल्टी प्रोसेसिंग मैप() फ़ंक्शन भी प्रदान करता है, जो क्लाउड पर आपके मानचित्र को ऑफ़लोड कर सकता है।

-1

मुझे लगता है कि ऐसा कोई कार्य करने का कोई कारण नहीं होगा। सभी पायथन थ्रेड को एक ही सीपीयू पर निष्पादित करना होता है। मान लें कि आपके मानचित्र फ़ंक्शन में कोई I/O घटक नहीं है, आपको प्रसंस्करण में कोई गति दिखाई नहीं देगी (और संदर्भ स्विचिंग के कारण शायद मंदी दिखाई देगी)।

अन्य पोस्टर्स ने मल्टीप्रोसेसिंग का उल्लेख किया है - यह शायद एक बेहतर विचार है।

+0

तो क्या पाइथन मल्टीथ्रेडिंग वास्तव में खराब है? क्या आपके पास इस जानकारी पर कोई स्रोत है? – Sandro

+1

यह है "बुरा" बनाम "अच्छा" का सवाल नहीं - मैंने कुछ विशिष्ट और ठोस का उल्लेख किया है, जो कि पाइथन दुभाषिया थ्रेड को एकाधिक प्रोसेसर पर एक साथ निष्पादित करने की अनुमति नहीं देगा। परिणामस्वरूप, एक प्रोसेसर केवल एक चीज कर सकता है एक समय में, यह है कि विभिन्न थ्रेडों से सीपीयू ऑपरेशंस को एक प्रोसेसर पर इंटरलीव किया जाना चाहिए। एक थ्रेड से सभी निर्देशों को निष्पादित करने के बाद दूसरे धागे के सभी निर्देश राउंड-रॉबिन फैशन में निर्देशों को निष्पादित करने से धीमा नहीं हो सकते हैं (और वास्तव में तेजी से होगा, क्योंकि पहले मामले में – danben

+0

केवल एक संदर्भ स्विच होगा) – danben

0

शायद Unladen Swallow Python 3 कार्यान्वयन का प्रयास करें? यह एक प्रमुख परियोजना हो सकती है, और स्थिर होने की गारंटी नहीं है, लेकिन यदि आप इच्छुक हैं तो यह काम कर सकता है। फिर list or set comprehensions उपयोग करने के लिए उचित कार्यात्मक संरचना की तरह लग रहा है।

0

पायथन अब समवर्ती। फ्यूचर्स मॉड्यूल है, जो एकाधिक धागे या एकाधिक प्रक्रियाओं के साथ काम करने के लिए मानचित्र प्राप्त करने का सबसे आसान तरीका है।

https://docs.python.org/3/library/concurrent.futures.html

0

नीचे मेरी map_parallel कार्य है। यह map की तरह काम करता है, सिवाय इसके कि यह प्रत्येक तत्व को एक अलग थ्रेड में समानांतर में चला सकता है (लेकिन नीचे नोट देखें)। यह उत्तर another SO answer पर बनाता है।

import threading 
import logging 
def map_parallel(f, iter, max_parallel = 10): 
    """Just like map(f, iter) but each is done in a separate thread.""" 
    # Put all of the items in the queue, keep track of order. 
    from queue import Queue, Empty 
    total_items = 0 
    queue = Queue() 
    for i, arg in enumerate(iter): 
     queue.put((i, arg)) 
     total_items += 1 
    # No point in creating more thread objects than necessary. 
    if max_parallel > total_items: 
     max_parallel = total_items 

    # The worker thread. 
    res = {} 
    errors = {} 
    class Worker(threading.Thread): 
     def run(self): 
      while not errors: 
       try: 
        num, arg = queue.get(block = False) 
        try: 
         res[num] = f(arg) 
        except Exception as e: 
         errors[num] = sys.exc_info() 
       except Empty: 
        break 

    # Create the threads. 
    threads = [Worker() for _ in range(max_parallel)] 
    # Start the threads. 
    [t.start() for t in threads] 
    # Wait for the threads to finish. 
    [t.join() for t in threads] 

    if errors: 
     if len(errors) > 1: 
      logging.warning("map_parallel multiple errors: %d:\n%s"%(
       len(errors), errors)) 
     # Just raise the first one. 
     item_i = min(errors.keys()) 
     type, value, tb = errors[item_i] 
     # Print the original traceback 
     logging.info("map_parallel exception on item %s/%s:\n%s"%(
      item_i, total_items, "\n".join(traceback.format_tb(tb)))) 
     raise value 
    return [res[i] for i in range(len(res))] 

नोट: एक बात का ध्यान के अपवाद है। सामान्य map की तरह, उपर्युक्त फ़ंक्शन अपवाद उठाता है यदि इसका कोई उप-धागा अपवाद उठाता है, और पुनरावृत्ति को रोक देगा। हालांकि, समानांतर प्रकृति के कारण, इस बात की कोई गारंटी नहीं है कि सबसे पहला तत्व पहला अपवाद उठाएगा।

संबंधित मुद्दे