Форум сайта python.su
Добрый вечер!
Подскажите пожалуйста, через какой модуль лучше всего реализовывать такую задачку :
есть список URL картинок, которые можно скачать, например, с помощью urlretrieve,
хочется, чтобы скрипт умел загружать картинки параллельно, примерно по такой схеме -
новую параллельную загрузку не начинать, пока не закончили скачиваться, например, 10 уже имеющихся загрузок.
Оптимально ли будет просто написать цикл по циклу, в котором стартуются функции загрузки и применён метод join (или joinall)?
Так вот, через какой модуль лучше всего это делать - Threading или subprocess?
Может ли кто-нибудь подкинуть какой-нибудь готовый пример, где реализована параллельная загрузка?
Благодарю за внимание.
Офлайн
http://docs.python.org/library/multiprocessing.html
Отредактировано (Ноя. 8, 2011 17:40:04)
Офлайн
Потоков достаточно. Примерный алгоритм элементарен:
1. Создаёшь очередь Queue.
2. Заполняешь очередь (опционально, зависит от алгоритма).
3. Запускаешь 10 потоков, все они имеют один алгоритм.
4. Рабочий поток берёт из очереди задачу (если нет ничего – ждёт или или завершается, или завершается по спец. маркеру полученному из очереди) и выполняет её.
5. Главный поток пополняет очередь заданиями или нихрена не делает, ожидает завершения рабочих.
..bw
Офлайн
Снова добрый вечер!
Спасибо bw за наводку к подходу.
Остановился на таком подходе (код не совсем рабочий):
from Queue import Queue
from threading import Thread
source = [obj1, obj2, obj3]
num_worker_threads = ...
def do_work(item):
...
return result
def worker(q):
while True:
item = q.get()
do_work(item)
q.task_done()
q = Queue()
for i in range(num_worker_threads):
t = Thread(target=worker, args=(q,))
t.daemon = True
t.start()
for item in source:
q.put(item)
q.join()
def worker(q):
item = q.get()
do_work(item)
q.task_done()
Отредактировано (Ноя. 10, 2011 23:06:53)
Офлайн
> Хм, наверно из-за while True: тред и живет вечно)
> функцию worker переписать вот так
Плохо переписал, он там нужен.
Как я говорил, есть тысяча и один способ завершения рабочего потока, зависит от деталей, например от того как очередь пополняется:
1. Очередь заполнена до начала работы и если она опустошается, то это всё.
q = Queue.Queue()
while True:
try:
task = q.get_nowait()
except Queue.Empty:
break
do_somthing(task)
_go_home_yankee = object()
q = Queue.Queue()
while True:
task = q.get()
if task is _go_home_yankee:
break
do_somthing(task)
Отредактировано (Ноя. 13, 2011 08:56:29)
Офлайн