线程池与进程池
进程池与线程池
开进程开线程都需要消耗资源,只不过两者比较的情况线程消耗的资源比较少
在计算机能够承受范围之内最大限度的利用计算机
什么是池?
在保证计算机硬件安全的情况下最大限度的利用计算机
池其实是降低了程序的运行效率 但是保证了计算机硬件的安全
(硬件的发展跟不上软件的速度)
如何创建线程池/进程池?
模块导入 from concurrent.futures import ThreadPoolExecutor / ProcessPoolExecutor
生成一个线程池 / 进程池 对象
T = ThreadPoolExecutor() 括号内可以传参数指定线程池内的线程个数也可以不传 不传默认是当前所在计算机的cpu个数乘5
P = ProcessPoolExecutor() 默认是当前计算机cpu的个数
ps:池子中创建的进程/线程创建一次就不会再创建了至始至终用的都是最初的那几个这样的话节省了反复开辟进程/线程的资源
进程需要在 main 下提交任务 线程建议也这样
from concurrent.futures import ProcessPoolExecutor p = ProcessPoolExecutor(5) def task(n): print(n) if __name__ == '__main__': for i in range(10): p.submit(task, i)
创建一个函数 其实就是你的进程/线程执行的任务
使用 submit() 方法来提交任务 括号内的第一个参数是 执行的 任务(函数) 第二个是参数 用逗号隔开
且 submit是异步 朝线程池中提交任务 异步提交 (复习什么是同步 什么是异步)
同步: 提交任务之后 原地等待任务的返回结果 期间不做任何事
异步: 提交任务之后 不原地等待返回结果 直接执行下一行代码 结果是要的 通过其他方式来拿
submit 提交任务之后 任务完成 会有一个返回值 是一个对象
from concurrent.futures import ProcessPoolExecutor p = ProcessPoolExecutor(5) def task(n): print(n) if __name__ == '__main__': for i in range(10): res = p.submit(task, i) 我使用res来接收这个对象 print(res.result()) 其中有个方法可以查看结果 result
使用result 可以查看对象的结果 但是 不能直接在 submit后直接使用 result 因为 任务提交之后是不会直接 有放回结果的 而result就相当于 等待这个结果 那么 异步就会变成串行了
from concurrent.futures import ProcessPoolExecutor p = ProcessPoolExecutor(5) def task(n): print(n) return n**2 if __name__ == '__main__': a =[] for i in range(10): res = p.submit(task, i) a.append(res) p.shutdown() for i in a: print(i.result())
shutdown()方法 关闭进程/线程池入口 等待池子中所有的任务执行完毕之后 才会往下运行代码 相当于 join
异步回调机制:当异步提交的任务有返回结果之后,会自动触发回调函数的执行
方法 .add_done_callback() 括号内填一个函数名 函数需要有一个参数 这个参数会自动传入 他是 submit的放回对象
提交任务的时候 绑定一个回调函数 一旦该任务有结果 立刻执行对于的回调函数
from concurrent.futures import ProcessPoolExecutor p = ProcessPoolExecutor(5) def task(n): print(n) return n**2 def callback(m): print('>>>>', m.result()) if __name__ == '__main__': a =[] for i in range(10): p.submit(task, i).add_done_callback(callback)
线程池和进程池的操作几乎一样 唯一一点就是 进程的回调函数是 主线程执行的 而 线程池的回调函数是 谁腾出手来谁来干
趁自己还没死 多折腾折腾