Python3如何正确设置这个多处理作业?

2024-05-23 20:06:43 发布

您现在位置:Python中文网/ 问答频道 /正文

每个文件都有10000行的参数。我有5个自定义下载程序。每项工作可能需要5秒到2分钟。如果下载器当前不工作,如何创建遍历10000行的内容,并将每个作业分配给下载器?在

编辑:

对我来说困难的部分是每个Downloader都是一个类的实例,而实例之间的区别是我实例化5Downloader对象时指定的端口号。所以我有a = Downloader(port_number=7751) ... e = Downloader(port_number=7755)。那么,如果我使用Downloader我会使用a.run(row)。在

我如何将工人定义为a, b, c, d, e而不是downloader function?在


Tags: 文件对象实例run程序编辑number内容
2条回答

有很多方法可以做到这一点-最简单的方法是使用multiprocessing.Pool并让它为您组织工作人员-10k行并不算多,假设一个平均的URL甚至是一个完整的千字节长,它仍然只需要10MB的内存,而且内存很便宜。在

所以,只需读取内存中的文件并将其映射到multiprocessing.Pool以执行您的出价:

from multiprocessing import Pool

def downloader(param):  # our downloader process
    # download code here
    # param will hold a line from your file (including newline at the end, strip before use)
    # e.g. res = requests.get(param.strip())
    return True  # lets provide some response back

if __name__ == "__main__":  # important protection for cross-platform use

    with open("your_file.dat", "r") as f:  # open your file
        download_jobs = f.readlines()  # store each line in a list

    download_pool = Pool(processes=5)  # make our pool use 5 processes
    responses = download_pool.map(downloader, download_jobs)  # map our data, line by line
    download_pool.close()  # lets exit cleanly
    # you can check the responses for each line in the `responses` list

如果需要共享内存,也可以使用threading而不是multiprocessing(或multiprocessing.pool.ThreadPool作为替换)在单个进程中执行所有操作。一个线程对于下载来说已经足够了,除非您正在进行额外的处理。在

更新

如果您希望下载程序作为类实例运行,可以将downloader函数转换为Downloader实例的工厂,然后在url旁边传递实例化这些实例所需的内容。下面是一个简单的循环方法:

^{pr2}$

请记住,这不是最平衡的解决方案,因为它可能碰巧有两个Downloader实例运行同一个端口,但它将平均处理足够大的数据。在

{{7}如果你不想创建一个cd7端口的实例,你就不需要创建一个cd7端口的实例了。在

将10000行读入字符串列表。在

with open('foo.dat') as f:
    data = f.readlines()

假设数据不包括端口号,而编辑的问题提到了5个端口,则应该将其添加到数据中。在

^{pr2}$

编写一个函数,将其中一个元组作为参数,拆分它,创建一个下载器对象并运行它。在

def worker(target):
    port, params = target
    d = Downloader(port_number=port)
    d.run(params)
    return params # for lack of more information.

使用multiprocessing.Pool^{}方法,将您定义的函数和元组列表作为参数。在

imap_unordered返回的迭代器将在结果可用时立即开始生成结果。你可以打印出来以显示进度。在

p = multiprocessing.Pool()
for params in p.imap_unordered(worker, data):
    print('Finished downloading', params)

编辑

注:如果你使用的Downloader对象的唯一方法是run(),那么它不应该是一个object。这是伪装的功能!在Youtube上查找“停止写作课程”视频并观看。在

相关问题 更多 >