Пул потоков. Модуль Threading.
Я думаю, пример из SEO-софта на тему пула потоков долго искать не придется. Взять тот же Хрумер. Указал количество потоков, например 20, запустил – все 20 работают, как только один из них завершит работу – запускается следующий и так, пока не закончатся ссылки. Наверное в 9 из 10 случаев я пишу скрипт с использованием пула потоков. Рассмотрим некторые примеры.
Пример 1. «В лоб».
threads = [] for x in range(THREADS): new_thread = threading.Thread(target=step_one) threads.append(new_thread) new_thread.start() time.sleep(1) while True: # какое-то условие for y in threads[:]: if not y.isAlive(): threads.remove(y) new_thread = threading.Thread(target=step_one) threads.append(new_thread) new_thread.start() time.sleep(0.1) while threading.activeCount()>0: time.sleep(5)
Функцию step_one запускаем в несколько потоков, все созданные потоки храним в списке. Затем провереяем в цикле какие потоки завершили работу и, если такие есть, создаем новые и так, пока не достигнем какого-либо результата. Криво, неудобно, зато сразу понятно. Достаточно долго пользовался такой реализацией, а всё из-за лени.
Пример 2. Семафоры.
import time import threading max_potokov = 20 maxconnections = 5 akkiQueue = threading.BoundedSemaphore(value=maxconnections) def doform(): akkiQueue.acquire() # код функции akkiQueue.release() for i in xrange(max_potokov): time.sleep(1) p = threading.Thread(target=doform) p.setDaemon(True) p.start() while threading.activeCount()>0: time.sleep(5)
Уже лучше, количество потоков контролируется, но надо заранее знать сколько будет потоков, в общем как-то изворачиваться если тебе надо будет прервать все эти потоки по условию.
Пример 3. Очереди.
queue = Queue.Queue() # создаем очередь def register(item): #Функция с основным кодом return def repeat(): while True: try: item = queue.get_nowait() # ждём данные except Queue.Empty: break register(item) # передаем данные в нашу функцию time.sleep(0.5) queue.task_done() # задача завершена for item in range(MAX_THREADS): queue.put(item) # заносим данные в очередь for i in xrange(THREADS): t = threading.Thread(target=repeat) # создаем нить t.start() # стартуем time.sleep(0.5) queue.join() # блокируем очередь до завершения
Здесь используется модуль Queue. На данный для меня самый удобный варинат – и выглядит красиво, и данные передавать можно.
Помимо тех вариантов, что я описал, можно погуглить на тему threadpool и найти какие-нибудь модули для организации пула потоков.
О! Я нашёл таки человека со схожими интересами.
Тоже юзаю сео и тоже юзаю питон ))
Щас вот сооружаю скриптец на тему автопостинга неких ссылок, получаемых с некоего сервера, в некий фрихостовый хост с пузами )
Точнее, несколько фрихостовых хостов =)
Подумал, что было бы круто сразу получать ссыли с сервака и в этом же время получать код поста с фрихоста для сравнения с кодом ссылок.
Вот и пошёл гулять по просторам преимущественно рунета, дабы освоить многопоточность в Пайтоне.
Бум дружить?
ЗЫ. Подписываюсь на тебя
ЗЗЫ. У меня в ЖЖ стоят ссыли верхним постом. Там может оказаться и порно всякое и прочее – не пугайся. Монетизируюсь )
ЗЗЗЫ. Ася моя, если чо – 7622763
Крайст
11 Янв 10 at 17:44
Да без проблем, давай дружить, контакты я тож указал если что. Своим сообщением ты мотивировал меня на новый пост, ушел делать=)
kalombo
11 Янв 10 at 20:00
А между потоком и основной частью программы возможно взаимодействие?
Т.е. поток, отсылает данные о своих действиях – завершен на 65%, регаю, логинюсь и тп
Alex Volkov
22 Янв 10 at 00:41
Дак просто:
print «Регистрируюсь»
в функции, которая запускается отдельным потоком.
Можно вообще не блокировать очередь в 3м примере, убрав строчку queue.join() и продолжать что-то делать в главном потоке, только за остальными надо будет уже следить вручную.
kalombo
22 Янв 10 at 01:19
А засуспендить\возобновить поток получится? Отдельно от других потоков, то есть 10 работают а один ждет?
P.S. Поставь еще плз плуг для извещения об ответах на мыло, а то не очень удобно блог постоянно открытым держать
Alex Volkov
22 Янв 10 at 01:25
Да можно наверняка. Глянь тут http://docs.python.org/library/threading.html, не приходилось мне суспендить.
kalombo
22 Янв 10 at 13:04
Вопрос про примеры 2,3. Что если функция выполняемая множеством потоков. Ловит эксепшен, или вообще нить виснет на каком-нибуть особо долгом сайте.
SeoMazzi
5 Фев 10 at 20:48
Оберни её в try-except.
kalombo
9 Фев 10 at 20:27
А select() или twisted юзать не пробовал?
-
31 Авг 11 at 06:25