2016-02-02 6 views
-2

Как ограничить максимум открытых потоков до 20 в следующем коде? Я знаю, что в прошлом были какие-то схожие вопросы, но я специально хочу знать, как это лучше всего делать с очередью и, если возможно, с рабочим примером.Рабочий пример очереди очереди

# b is a list with 10000 items 
    threads = [threading.Thread(target=targetFunction, args=(ptf,anotherarg)) for ptf in b] 
    for thread in threads: 
     thread.start() 

    for thread in threads: 
     thread.join() 
+0

Вы пробовали 'b [: 20]'? Или вы хотите обработать весь диапазон с помощью 20 потоков max? Это не совсем понятно в вашем вопросе. –

+0

# b - это список из 10000 элементов и не может быть изменен – Nickpick

+1

, поэтому используйте threadpool и вытащите 'targetFunction' из очереди, чтобы получить его работу? –

ответ

6

Простой способ сделать это с queue.Queue для работы и запуска нити с for _ in range(MAXTHREADS): threading.Thread(target=f, args=(the_queue,)).start(). Тем не менее, я считаю, что это легче читать с помощью подкласса Thread. Ваш пробег может отличаться.

import threading 
import queue 

class Worker(threading.Thread): 
    def __init__(self, q, other_arg, *args, **kwargs): 
     self.q = q 
     self.other_arg = other_arg 
     super().__init__(*args, **kwargs) 
    def run(self): 
     while True: 
      try: 
       work = self.q.get(timeout=3) # 3s timeout 
      except queue.Empty: 
       return 
      # do whatever work you have to do on work 
      self.q.task_done() 

q = queue.Queue() 
for ptf in b: 
    q.put_nowait(ptf) 
for _ in range(20): 
    Worker(q, otherarg).start() 
q.join() # blocks until the queue is empty. 

Если вы настойчивы об использовании функции, я предлагаю оборачивать ваш targetFunction с чем-то, что знает, как получить из очереди.

def wrapper_targetFunc(f, q, somearg): 
    while True: 
     try: 
      work = q.get(timeout=3) # or whatever 
     except queue.Empty: 
      return 
     f(work, somearg) 
     q.task_done() 

q = queue.Queue() 
for ptf in b: 
    q.put_nowait(ptf) 
for _ in range(20): 
    threading.Thread(target=wrapper_targetFunc, 
        args=(targetFunction, q, otherarg)).start() 
q.join() 
+0

Это выглядит неплохо, но в моем коде будут внесены некоторые изменения, если я хочу поместить его в класс. Есть ли способ просто вызвать функцию вместо этого? – Nickpick

+0

@Nicolas проверить мои изменения. Мне это гораздо труднее читать, но, как я сказал в верхней части моего вопроса: YMMV –

+0

выглядит почти идеально, но targetFunction, но, видимо, целевая функция теперь требует двух аргументов. Мне нужно передать q в это (это только косметическая проблема). В противном случае отлично работает. Благодаря! – Nickpick

Смежные вопросы