Одновременная загрузка и обработка больших файлов в Python
У меня есть список URL для загрузки больших файлов (например, сжатых архивов), которые я хочу обработать (например, распаковать архивы).
Как загрузка, так и обработка занимают много времени, а обработка дискового ввода-вывода требует значительных ресурсов, поэтому я хочу, чтобы одновременно выполнялся только один из них. Поскольку две задачи занимают примерно одно и то же время и не конкурируют за одни и те же ресурсы, я хочу загрузить следующий файл (-ы) во время обработки последней.
Это вариация проблемы производитель-потребитель.
Ситуация схожа с чтением и обработкой изображений или загрузкой файлов, но мои вызовы загрузчика (пока) не могут быть разборчивы, поэтому я не смог использовать многопроцессорность, и обе задачи занимают примерно одно и то же время.
Вот фиктивный пример, где загрузка и обработка блокируются:
import time
import posixpath
def download(urls):
for url in urls:
time.sleep(3) # this is the download (more like 1000s)
yield posixpath.basename(url)
def process(fname):
time.sleep(2) # this is the processing part (more like 600s)
urls = ['a', 'b', 'c']
for fname in download(urls):
process(fname)
print(fname)
Как я могу сделать две задачи одновременно? Могу ли я использовать yield
или же yield from
умным способом, возможно, в сочетании с deque
? Или это должно быть asyncio
с Future
?
2 ответа
Я бы просто использовал threading.Thread(target=process, args=(fname,))
и начать новый поток для обработки.
Но перед этим закончим последний поток обработки:
t = None
for fname in download(urls):
if t is not None: # wait for last processing thread to end
t.join()
t = threading.Thread(target=process, args=(fname,))
t.start()
print('[i] thread started for %s' % fname)
Год спустя мы фактически используем Python 3 asyncio
а также aiohttp
,