回调函数和池
# 1000个螺丝 1000个任务 # 制作设备只有4个 CPU的个数 # 顾几个人? 开多少个进程 import os import time from concurrent.futures import ProcessPoolExecutor def make(i): time.sleep(1) print('%s 制作螺丝%s'%(os.getpid(),i)) return i**2 if __name__ == '__main__': p = ProcessPoolExecutor(4) # 创建一个进程池,表示可以同时掉那个的cpu个数 for i in range(100): p.submit(make,i) # 向进程池中提交任务 p.shutdown() # 阻塞 直到池中的任务都完成为止 print('所有的螺丝都制作完了') p.map(make,range(100)) # submit的简便用法 # 接收返回值 ret_l = [] for i in range(100): ret = p.submit(make,i) ret_l.append(ret) for r in ret_l: print(r.result()) ret = p.map(make, range(100)) for i in ret: print(i) # 回调函数 import time import random def func1(n): time.sleep(random.random()) print('in func1 %s'%n) return n*2 def call_back(arg): print(arg.result()) if __name__ == '__main__': p = ProcessPoolExecutor(4) for i in range(10): ret = p.submit(func1,i) ret.add_done_callback(call_back) # 回调函数即使在这个线程对应的函数执行完毕之后立即执行的函数 # 参数为函数的返回值 ret_l = [] for i in range(10): ret = p.submit(func1, i) ret_l.append(ret) for r in ret_l: call_back(r) # 也可以使用for的call_back方法回调函数,参数依然为上一个函数的返回值 # 1.不能有多少个任务就开多少个进程,这样开销太大了 # 2.用有限的进程执行无限的任务,多个被开启的进程重复利用,节省的是开启\销毁\多个进程切换的时间 # 3.回调函数是谁执行的?(主进程?子进程