2014-09-29 21 views
11

Burada python diş nasıl yapılacağı hakkında aradık, ama bugüne kadar i lüzum cevap almak mümkün olmamıştır. Burada mevcut anwsers bazı Kuyruk ve Threading piton sınıfları ile ve bu nedenle çok aşina değilim bana hiç mantıklı.Python'da bir iş parçacığı havuzundan sonuçlar nasıl elde edilir?

Farklı görevler verebileceğim ve hepsinin sonuç değerlerini sona erdirip sonuçta işledikleri bir iş parçacığı havuzu oluşturmak istiyorum. Şimdiye kadar bunu yapmaya çalıştım ama sonuçları elde edemiyorum. numara verilen sözcük verilen süreleri ile

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 

çıktı baskılar dizeleri ancak sonuç listesi Yok değerlerle dolu, yani nereye ı değer işlev dönüş değerleri koymalıyız i yazdım koddur.

Veya kolay yolu i Kuyruk dolduracak bir listesini oluşturmak ve bir sözlük ya da benim işlevine argüman olarak sonucu depolamak için bazı değişkeni eklemektir ve görev Kuyruğa eklendikten sonra bu sonuç argümanı eklemek Sonuçların listesi:

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 

Yardımlarınız için çok müteşekkir olacağım.

cevap

9

Python aslında bir sen, its just not well documented kullanabilirsiniz yerleşik iş parçacığı havuzu etti:

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 

Ya (map yerine apply_async kullanarak):

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

ikinci vaka yararlı olacaktır zaman sayı Görev, havuzun büyüklüğü ile aynı, değil mi? –

+0

İstenilen sayıda görevle ve herhangi bir sayıda işçi ile bir "Havuz" ile iyi çalışacaktır. 'map', yinelenen tüm öğelere karşı bir işlev çalıştırmak ve her aramanın sonuçlarını döndürmek için kullanışlıdır. 100 numaraya kadar tekrarlanabilecek 5 işçiniz varsa, 'Pool' fonksiyonu tüm 100 öğeye karşı arayacak ancak aynı anda 5'ten fazla iş parçacığı çalıştırmayacaktır. Çıkış, tüm işlev çağrılarının sonuç değeriyle 100 uzunluğu yinelenebilir olacaktır. çünkü [GIL] Bir diğer not – dano

+1

@RafaelRios, (https://wiki.python.org/moin/GlobalInterpreterLock), Python CPU bağlı işi yapmak için iplikler kullanılarak herhangi bir performans yararı vardır. Bu kısıtlamaya etrafında almak için, bunun yerine [ 'multiprocessing'] (https://docs.python.org/2.7/library/multiprocessing.html) modülü üzerinden çoklu süreçleri kullanmak gerekir. Yukarıdaki örnekte, '' multiprocessing.pool import ThreadPool' 'yerine '' çoklu işlemden ithal havuz' 'kullanarak geçiş yapabilirsiniz. Diğer her şey aynı kalır. – dano