Python线程池实现的进阶知识

2023-12-30 23:27:16

1.参数 max_workers 的设定

接前文 《Python多线程和线程池的下载实战用法 》中案例,继续分析
concurrent.futures.ThreadPoolExecutor() 是 Python 中的一个线程池实现,用于执行并发的任务。它可以通过参数 max_workers 来设置线程池的最大工作线程数。

在你提供的代码中,使用 ThreadPoolExecutor() 构建了一个线程池执行器,并通过列表推导式将 download_with_delay(url) 函数提交给线程池执行。这样可以并发地下载多个 URL。

区别在于是否指定 max_workers 参数:

  1. 不指定 max_workers 参数:如果不指定 max_workers 参数,ThreadPoolExecutor() 会根据系统自动选择一个合适的默认值作为最大工作线程数。这意味着线程池会根据需要动态调整线程数量,以适应当前的任务负载。

    with concurrent.futures.ThreadPoolExecutor() as executor:
        [executor.submit(download_with_delay, url) for url in urls]
    
  2. 指定 max_workers 参数:如果指定了 max_workers 参数,线程池会创建一个固定数量的工作线程。这些线程会被循环利用,直到所有任务完成。

    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        [executor.submit(download_with_delay, url) for url in urls]
    

指定 max_workers 参数可以控制线程池中的并发线程数量。根据具体的情况,你可以根据系统资源和任务需求来调整最大工作线程数。如果任务较少或资源有限,可以选择较小的值;如果任务较多且有足够的资源,可以选择较大的值。

需要注意的是,过多的线程数量可能会导致资源竞争和性能下降,因此需要根据实际情况进行调整。

2. max_workers 参数好还是不指定参数好

对于 ThreadPoolExecutor() 中的 max_workers 参数,是否指定应该根据具体情况而定。不同的情况下,可能需要不同的线程池配置。

如果你的系统资源有限,或者任务量较小,那么可以考虑不指定 max_workers 参数,让线程池根据需要动态调整线程数量,以避免占用过多的资源。

但是如果你的系统拥有足够的资源,并且需要处理大量的并发任务,那么可以通过指定 max_workers 参数来控制线程池中的并发线程数量。这样可以确保系统不会使用过多的资源,并提高任务执行效率。

另外,需要注意的是,在实际开发中,还需要考虑以下因素:

  • 任务及其执行时间:如果任务需要花费较长的时间才能完成,那么较大的线程池可能会占用过多的资源,导致整个系统的性能下降。
  • 系统资源:如果系统资源有限,那么较大的线程池可能会导致系统崩溃或出现其他问题。
  • 线程安全:线程池中的线程需要保持线程安全,避免出现数据竞争、死锁等问题。

因此,在实际开发中,需要综合考虑以上因素来确定是否需要指定 max_workers 参数,并根据具体情况进行调整。

3.如果考虑线程安全,该怎么指定max_workers 参数

在考虑线程安全时,需要确保多个线程并发执行时不会导致数据不一致或其他并发问题。对于 ThreadPoolExecutor() 中的 max_workers 参数,指定参数与线程安全本身没有直接关联,但是可以通过控制并发线程数量来间接影响线程安全。

在考虑线程安全时,可以采取以下措施:

  1. 使用线程安全的数据结构:选择使用线程安全的数据结构(例如 queue.Queue)来存储共享数据,以避免多个线程同时修改数据导致的问题。

  2. 合理地控制并发度:通过指定 max_workers 参数来控制线程池中的并发线程数量,避免因线程过多而导致资源竞争和性能下降。根据系统资源和任务需求,合理地设置最大工作线程数。

  3. 使用锁或同步机制:在必要的情况下,可以使用锁或其他同步机制来保护共享资源,确保多个线程访问时的线程安全性。

  4. 编写线程安全的代码:在编写并发代码时,需要考虑多线程并发执行可能带来的问题,编写线程安全的代码逻辑,避免出现数据竞争、死锁等问题。

在实际开发中,需要根据具体情况综合考虑上述因素,并根据需求来选择合适的线程安全策略和线程池配置。同时,也可以通过测试和性能分析来验证线程安全性和并发性能,从而优化线程池的配置参数。

4.经典案例

需求

有几万条数据,如果单个数据处理挨个处理的话,涉及下载,指定pdf文件进行ocr识别,其他pdf文件需求识别文件校验,最后把校验结果放在excel里,如何设计代码逻辑,使效率更快

分析

处理大量数据时,优化代码逻辑可以提高效率。根据你的描述,以下是一种可能的代码逻辑设计:

  1. 使用多线程或异步操作:将下载、OCR识别和校验等任务分配给多个线程或异步操作,以实现并发处理。这样可以节省等待时间,并提高整体处理速度。

  2. 使用连接池进行下载:使用连接池来管理下载请求,避免频繁地创建和关闭连接,提高下载效率。可以使用第三方库(如requests)提供的连接池功能。

  3. 并行执行OCR识别和文件校验:对于不同的PDF文件,可以同时进行OC

文章来源:https://blog.csdn.net/m0_57021623/article/details/135277449
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。