进程池 & 线程池
https://www.cnblogs.com/lddragon/p/11358948.html # 抄的
进程池与线程池
什么是池?
在保证计算机硬件安全的情况下最大限度的利用计算机
池其实是降低了程序的运行效率,但是保证了计算机硬件的安全
(硬件的发展跟不上软件的速度)
进程池与线程池
开进程开线程都需要消耗资源,只不过两者比较的情况 线程消耗的资源比较少
在计算机能够承受范围之内最大限度的利用计算机
如何创建线程池 / 进程池?
模块导入 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(n): # 这里面的n是任务task函数执行完毕后的返回结果 print('>>>>', n.result()) if __name__ == '__main__': a =[] for i in range(10): p.submit(task, i).add_done_callback(callback)