【问题标题】:Multithreaded downloader slows down for no reason多线程下载器无故变慢
【发布时间】:2020-11-03 03:21:40
【问题描述】:

我一直在使用 requestsmultiprocessing.dummy 在 Python 中开发多线程图像抓取工具。

脚本运行良好,直到达到某个点。然后整个工作流程变得非常缓慢。此外,我越早体验到这一点,似乎使用的线程越多。

下载部分如下所示:

def download(URL):
    try:
        URL = URL.rstrip()    
        down = requests.get(URL, headers={'x-test2': 'true'})
        # Download Images 

    except BaseException as e:
        print("Error")

线程部分看起来像:

if __name__ == '__main__':
    ThreadPool(20).map(download, URLlist)   

所以我的问题是,是什么减慢了我的整个下载过程,因为网址很好,它应该像以前一样继续。有没有我遗漏的命令或者是我的线程部分的东西? (线程没有正确关闭...)

同样重要的是,这个问题不会出现在较小的 url 列表中。

(但这不应该是我下载的页面的请求限制问题,因为同时脚本正在运行并且在我在页面速度和可用性方面遇到 0 个问题之后)。这是为什么呢?

【问题讨论】:

  • 您可以尝试偶尔关闭您的线程池并重新打开它。 Python mp.Pool() 有一个问题,如果你让池长时间/迭代打开,它会变慢。我不确定 ThreadPool,但可以尝试一下。
  • 你有多少个 CPU 内核?拥有比 CPU 更多的线程可能会阻碍无济于事。您也无法使用 Python 线程获得真正的并行性,因为由于 CPython 的 GIL(全局解释器锁),一次只能运行一个线程运行 Python 代码。像这样的 I/O 绑定操作可能不会受到影响,但是使用 multiprocessing 而不是 threading 模块,CPU 绑定操作会更好。
  • @MarkTolonen 我有 6 个核心,即使没有使用它们。我在多处理方面也遇到了同样的问题,但经过一些测试后,它似乎可以与 concurrent.futures' 一起使用,除了高 CPU 使用率。
  • @bivouac0 你能解释一下如何存档吗?我是所有这些东西的初学者。

标签: python multithreading multiprocessing threadpool python-multiprocessing


【解决方案1】:

如果池操作在一段时间内变慢,则每隔一段时间关闭池可能(或可能不会)有帮助。尝试像这样简单的事情......

if __name__ == '__main__':
    max_size = # use some large value here
    for i in range(0, len(URLlist), max_size):
        st = time.time()
        pool = ThreadPool(20)    
        pool.map(download, URLlist[i: i + max_size])
        pool.close()    # should not be needed in practice
        pool.join()
        et = time.time()
        print('Processing took %.3f seconds' % (et-st))

尝试一些不同但较大的 max_size 值。这是您的代码在关闭池并打开另一个池之前将处理的 URL 列表中的数字元素。

正如我在评论中所说,我知道 multiprocessing.Pool() 存在此问题,但我不确定 ThreadPool() 是否存在相同问题。对于 mp.Pool(),这只发生在要处理的项目列表非常大的情况下。发生这种情况时,您通常会看到内存使用量随着程序运行而不断增加(因此请查找此内容)。我认为根本问题是池工作者会一遍又一遍地创建,但在您关闭池之前不会正确地进行垃圾收集。

需要考虑的另一件事... 某些 URL 可能需要很长时间才能处理,并且在您的代码运行一段时间后,您的许多线程可能会因较慢的 URL 而陷入困境,从而使事情看起来很慢整体下降。如果是这种情况,偶尔关闭池也无济于事。

【讨论】:

  • 一个池有maxtasksperchild 选项。
猜你喜欢
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
相关资源
最近更新 更多