3

我有一个要下载的大文件(例如压缩档案)的 URL 列表,我想要处理(例如解压缩档案)。

下载和处理都需要很长时间,并且磁盘 IO 上的处理很重,所以我希望一次只运行一个。由于这两个任务花费大约相同的时间并且不竞争相同的资源,我想在处理最后一个文件时下载下一个文件。

这是生产者-消费者问题的变体。

这种情况类似于读取和处理图像下载大量文件,但我的下载器调用(还)不是可挑选的,所以我无法使用多处理,并且这两个任务大约需要相同的时间。

这是一个虚拟示例,其中下载和处理都是阻塞的:

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)

我怎样才能使这两个任务并发?我可以使用yieldyield from 以一种聪明的方式,也许结合使用deque?还是必须asyncioFuture

4

2 回答 2

1

一年后,我们实际上正在使用 Python 3asyncioaiohttp.

于 2017-11-15T14:25:12.467 回答
0

我只需使用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)

请参阅https://docs.python.org/3/library/threading.html

于 2016-09-21T22:01:21.650 回答