【python内功修炼011】:Python进程池和线程池详解

本文介绍了Python中的进程池和线程池,讲解了它们的概念、区别以及创建方法。重点讨论了concurrent.futures模块,包括Executor.submit创建线程池和进程池,以及Future对象的使用。文中还提供了实例代码,展示了如何使用进程池和线程池进行同步和异步操作。
摘要由CSDN通过智能技术生成

一、关于线程池\进程池介绍

1.1 池的概念

  • 池是一组资源的集合,这组资源在程序启动时就完全被创建并初始化,这也称为为静态资源分配

  • 程序从系统(内存)调用和分配资源,包括之后释放资源都需要耗费大量时间。如果把相关资源放在“池“中,程序从池中获取和释放,无需动态分配,无疑速度要快很多。

  • 池相当于服务器管理系统资源的应用设施,它避免了服务器对内核的频繁访问。

池的概念主要目的是为了重用:让线程或进程在生命周期内可以多次使用。它减少了创建创建线程和进程的开销,“以空间换时间”,来提高了程序性能。重用不是必须的规则,但它是程序员在应用中使用池的主要原因。

1.2 池的划分

池可以分为多种,常见的有内存池进程池线程池连接池

1.3 线程池和进程池的区别

线程池和进程池相似,用法基本一致。主要是应用场景的不同,在判断对程序是否进行线程池或进程池操作时,得先看程序业务。

业务 用途 建议使用
IO密集型 读取文件,读取网络套接字频繁等。 线程池
计算密集型 大量消耗CPU的数学与逻辑运算,也就是我们这里说的平行计算。 进程池,利用硬件多核优势

1.5 进程池的创建(流程)

  • 创建进程池,在池内放入合适数量的进程
  • 将事件加入进程池的等待队列
  • 使用进程池内的进程不断的执行等待事件,直到所有事件执行完毕
  • 所有事件处理完毕后,关闭进程池,回收进程池

二、创建线程池\进程池的两种方法

从Python3.2python标准库为我们提供了concurrent和multiprocessing模块编写相应的异步多线程/多进程代码。

2.1 concurrent和multiprocessing区别

两个模块本质区别并不大,有的也只是调用方式略有差异。先有的 multiprocessing,后有concurrent.futures,后者的出现就是为了降低编写代码的难度,后者的学习成本较低。

本博文主要以介绍 concurrent.futures模块为主。

三、concurrent.futures模块

3.1 模块的介绍

从 Python3.2开始,Python 标准库提供了 concurrent.futures 模块,为开发人员提供了启动异步任务的高级接口。

concurrent.futures模块的基础是Exectuor,Executor是一个抽象类,它不能被直接使用。但是它提供的两个子类ThreadPoolExecutor和ProcessPoolExecutor却是非常有用,顾名思义两者分别被用来创建线程池和进程池的代码。我们可以将相应的tasks直接放入线程池/进程池,不需要维护Queue来操心死锁的问题,线程池/进程池会自动帮我们调度。

3.2 Executor.submit 创建进程/线程池

进程/线程池,只有固定个数的线程/进程,通过 max_workers 指定。

  • 任务通过 Executor.submit 提交到 executor 的任务队列,返回一个 future 对象。

  • Future 是常见的一种并发设计模式。一个Future对象代表了一些尚未就绪(完成)的结果,在「将来」的某个时间就绪了之后就可以获取到这个结果。

  • 任务被调度到各个 workers 中执行。但是要注意:

    • 一个任务一旦被执行,在执行完毕前,会一直占用该 worker!
    • 如果 workers 不够用,其他的任务会一直等待! 因此 Executor不适合实时任务。

简易创建进程池示例:

'''
Executor.submit 创建进程实例
'''

from concurrent.futures import ProcessPoolExecutor
import time,  os

# 打印信息
def print_info(n):
    print("%s: 开启" % os.getpid())
    time.sleep(1)
    return n**2

if __name__ == '__main__':
    pool = ProcessPoolExecutor(4)  # 开启四个进程

    for i in range(10):  # 执行10个任务
        pool.submit(print_info, i)

四、concurrent.futures 常用模块

concurrent.futures 包含三个部分的 API:

4.1 Executor模块

也就是两个执行器的 API

  • 构造器:主要的参数是 max_workers,用于指定线程池大小(或者说 workers 个数)

  • submit(fn, *args, **kwargs)  
    
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值