首页 > 解决方案 > Python 多处理数组中的所有函数

问题描述

我想在 Python 中有一个函数数组。像那样:

def download(x,y):
      r = requests.get(x, allow_redirects=True)
      open(y, 'wb').write(r.content)

array = [download(url,filename),download(url2,filename2)]

现在我想使用多处理或多线程(取决于哪个更好)同时运行所有这些。

但是函数的数量可能会增加,因此我正在努力运行多线程。

有什么建议么?

标签: pythonmultithreadingmultiprocessingpython-multiprocessingpython-multithreading

解决方案


使用多处理,类似这样的东西。

  • 这是使用进程池;对于网络 IO 绑定操作,您可以multiprocessing.pool.ThreadPool()改为运行单个进程。
  • 默认情况下,Pool()为您拥有的每个 CPU 生成一个工作器。您可能希望向上或向下调整。
  • 使用requestsSession 比requests.get()直接使用更有效(TCP、HTTP、TLS 开销)。
  • 你失踪了resp.raise_for_status();这意味着您最终可能会保存 404 或 500 响应,就好像一切正​​常一样。(您现在可能希望添加一些异常处理;任何失败的作业都会向上传播以关闭池并终止其他作业。)
  • 使用stream=Trueandresp.iter_content()将避免将内容缓冲到内存中。
  • imap_unordered()是高级池操作中最快的,但顾名思义,失去了作业的顺序。在这种情况下应该没关系。
  • 如果你有更多的工作,你可以通过参数优化一些池开销chunksize,这基本上意味着单个工作人员将被发送多个工作项。
import multiprocessing
import requests

sess = requests.Session()


def download(job):
    url, filename = job
    resp = sess.get(url, allow_redirects=True, stream=True)
    resp.raise_for_status()
    with open(filename, "wb") as f:
        for chunk in resp.iter_content(524288):
            f.write(chunk)


def main():

    jobs = [
        (url, filename),
        (url2, filename2),
    ]

    with multiprocessing.Pool() as p:
        for _ in p.imap_unordered(download, jobs):
            pass


if __name__ == "__main__":
    main()

推荐阅读