2014-09-29 10 views
11

मैंने यहां पाइथन में थ्रेडिंग करने के बारे में बताया है, लेकिन अब तक मुझे जवाब देने में सक्षम नहीं है। मैं क्यूई और थ्रेडिंग पायथन कक्षाओं से बहुत परिचित नहीं हूं और इसी कारण से यहां मौजूद कुछ श्रमिकों को मुझे कोई मतलब नहीं है।पायथन में धागे के पूल से परिणाम कैसे प्राप्त करें?

मैं धागे का एक पूल बनाना चाहता हूं जो मैं अलग-अलग कार्य दे सकता हूं और जब वे सभी समाप्त हो जाते हैं तो परिणाम मूल्य प्राप्त होते हैं और उन्हें संसाधित करते हैं। अभी तक मैंने ऐसा करने की कोशिश की है लेकिन मैं परिणाम प्राप्त करने में सक्षम नहीं हूं। कोड मैं लिखा है है:

from threading import Thread 
from Queue import Queue 

class Worker(Thread): 
    """Thread executing tasks from a given tasks queue""" 
    def __init__(self, tasks): 
     Thread.__init__(self) 
     self.tasks = tasks 
     self.daemon = True 
     self.result = None 
     self.start() 
    def run(self): 
     while True: 
      func, args, kargs = self.tasks.get() 
      try: 
       self.result = func(*args, **kargs) 
      except Exception, e: 
       print e 
      self.tasks.task_done() 
    def get_result(self): 
     return self.result 

class ThreadPool: 
    """Pool of threads consuming tasks from a queue""" 
    def __init__(self, num_threads): 
     self.tasks = Queue(num_threads) 
     self.results = [] 
     for _ in range(num_threads): 
      w = Worker(self.tasks) 
      self.results.append(w.get_result()) 
    def add_task(self, func, *args, **kargs): 
     """Add a task to the queue""" 
     self.tasks.put((func, args, kargs)) 
    def wait_completion(self): 
     """Wait for completion of all the tasks in the queue""" 
     self.tasks.join() 
    def get_results(self): 
     return self.results 

def foo(word, number): 
    print word*number 
    return number 

words = ['hello', 'world', 'test', 'word', 'another test'] 
numbers = [1,2,3,4,5] 
pool = ThreadPool(5) 
for i in range(0, len(words)): 
    pool.add_task(foo, words[i], numbers[i]) 

pool.wait_completion() 
results = pool.get_results() 
print results 

उत्पादन प्रिंट शब्द दिए गए बार नंबर दिया साथ तार लेकिन परिणामों की सूची से कोई भी मूल्यों के साथ भरा हुआ है, तो मैं कहाँ समारोह की वापसी मान रखना चाहिए।

या एक आसान तरीका है जहां मैं कतार भरता हूं और परिणाम को मेरे फ़ंक्शन के लिए तर्क के रूप में संग्रहीत करने के लिए एक शब्दकोश या कुछ चर जोड़ता हूं, और कार्य को क्यू में जोड़ा जाने के बाद इस परिणाम तर्क को जोड़ता है परिणामों की एक सूची:

def foo(word, number, r): 
    print word*number 
    r[(word,number)] = number 
    return number 

words = ['hello', 'world', 'test', 'word', 'another test'] 
numbers = [1,2,3,4,5] 
pool = ThreadPool(5) 
results = [] 
for i in range(0, len(words)): 
    r = {} 
    pool.add_task(foo, words[i], numbers[i], r) 
    results.append(r) 
print results 

मैं आपकी मदद के लिए बहुत आभारी हूं।

उत्तर

9

अजगर वास्तव में एक अंतर्निहित थ्रेड पूल आप उपयोग कर सकते हैं, its just not well documented गया है:

from multiprocessing.pool import ThreadPool 

def foo(word, number): 
    print (word * number) 
    r[(word,number)] = number 
    return number 

words = ['hello', 'world', 'test', 'word', 'another test'] 
numbers = [1,2,3,4,5] 
pool = ThreadPool(5) 
results = [] 
for i in range(0, len(words)): 
    results.append(pool.apply_async(foo, args=(words[i], numbers[i]))) 

pool.close() 
pool.join() 
results = [r.get() for r in results] 
print results 

या (का उपयोग कर apply_async की map बजाय):

from multiprocessing.pool import ThreadPool 

def foo(word, number): 
    print word*number 
    return number 

def starfoo(args): 
    """ 

    We need this because map only supports calling functions with one arg. 
    We need to pass two args, so we use this little wrapper function to 
    expand a zipped list of all our arguments. 

    """  
    return foo(*args) 

words = ['hello', 'world', 'test', 'word', 'another test'] 
numbers = [1,2,3,4,5] 
pool = ThreadPool(5) 
# We need to zip together the two lists because map only supports calling functions 
# with one argument. In Python 3.3+, you can use starmap instead. 
results = pool.map(starfoo, zip(words, numbers)) 
print results 

pool.close() 
pool.join() 
+0

दूसरे मामले में उपयोगी हो सकता है जब संख्या कार्य का आकार पूल के आकार जैसा ही है, है ना? –

+0

यह किसी भी कार्य के साथ ठीक से काम करेगा, और 'पूल' के साथ किसी भी श्रमिक के साथ काम करेगा। 'नक्शा' उपयोगी है यदि आप एक पुनरावर्तनीय सभी वस्तुओं के खिलाफ एक फ़ंक्शन चलाने के लिए चाहते हैं, और प्रत्येक कॉल के परिणाम वापस कर दें। एफएफ में आपके पास 5 श्रमिकों की लंबाई 100 के बराबर है, 'पूल' सभी 100 वस्तुओं के खिलाफ फ़ंक्शन को कॉल करेगा, लेकिन साथ ही 5 से अधिक थ्रेड कभी भी नहीं चलाएगा। आउटपुट सभी फंक्शन कॉल के परिणाम मूल्य के साथ लंबाई 100 का एक पुनरावर्तनीय होगा। – dano

+1

@RafaelRios एक अन्य नोट, [GIL] (https://wiki.python.org/moin/GlobalInterpreterLock) की वजह से, पाइथन में सीपीयू-बाध्य काम करने के लिए धागे का उपयोग करने से कोई प्रदर्शन लाभ नहीं होता है। इस सीमा को पाने के लिए, आपको इसके बजाय ['multiprocessing'] (https://docs.python.org/2.7/library/multiprocessing.html) मॉड्यूल के माध्यम से एकाधिक प्रक्रियाओं का उपयोग करने की आवश्यकता है। ऊपर दिए गए उदाहरण के लिए, आप 'multiprocessing.pool आयात थ्रेडपूल' से 'मल्टीप्रोसेसिंग आयात पूल' से 'स्विच का उपयोग करके स्विच कर सकते हैं। बाकी सब कुछ वही रहता है। – dano

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