python 之并发编程更新版进程池与进程池比较与回调函数
一.更新版进程池与进程池比较
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor import os, time def func(i): print('Process', i, os.getpid()) time.sleep(0.1) print("Process..end") return 88899
# (1)ProcessPoolExcutor 进程池的基本使用(改良版)
相对于旧版的进程池,
一定会等待子进程全部执行完毕之后,再终止程序,相当于过去的Process流程
shutdown 相当于Process里面的join
if __name__ == "__main__": # (1)ProcessPoolExecutor() <==> Pool() p = ProcessPoolExecutor(5) # (2)submit() <==> apply_async() res = p.submit(func, 55) # (3)result() <==> get() res = res.result() print(res) # # (4)shutdown <==> close + join #p.shutdown() print("主进程执行结束...")
# (2)线程池
from threading import current_thread as ct def func(i): print("thread",i,ct().ident) time.sleep(0.1) print("thread %s end" % (i)) #可以在参数中指定并发的线程数 tp = ThreadPoolExecutor(10) for i in range(20): tp.submit(func,i) #tp.shutdown() print("主线程执行结束...")
# (3)线程池的返回值
from threading import current_thread as cthread def func(i): print("thread", i, cthread().ident) # 加延迟防止个别线程因为执行速度过快,又接收任务,阻碍新线程的创建 # time.sleep(0.1) print("threading %s end" % (i)) # return "*" * i return cthread().ident tp = ThreadPoolExecutor() lst = [] setvar = set() for i in range(10): res = tp.submit(func,i) lst.append(res) for i in lst: # print(i.result()) setvar.add(i.result()) print(setvar,len(setvar)) print("主线程执行结束...")
# (4)map 返回迭代器
from threading import current_thread as cthread def func(i): print("threading",i,cthread().ident) time.sleep(0.1) print("thread %s end" % (i)) return "*" * i tp = ThreadPoolExecutor(5) it = tp.map(func,range(20)) # map from collections import Iterable,Iterator print(isinstance(it,Iterator)) for i in it: print(i) tp.shutdown() print("主线程执行结束..")
二.回调函数
回调函数:
把函数当成参数传递的另外一个函数
函数先执行,最后在执行当参数传递的这个函数,整个过程是回调,这个参数是回调函数
# (1) 线程池的回调函数是由 子线程完成
from concurrent.futures import ThreadPoolExecutor from threading import current_thread as cthread import time def func(i): print("thread",i,cthread().ident) time.sleep(0.1) print("thread %s end" % (i)) return "*" * i # 定义成回调函数 def call_back(args): print("call back:",cthread().ident) print(args.result()) tp = ThreadPoolExecutor(5) for i in range(1,11): # submit(函数,参数).add_done_callback(要添加的回调函数) tp.submit(func,i).add_done_callback(call_back) tp.shutdown() print("主线程:",cthread().ident)
# (2) 进程池的回调函数是由 主进程完成
from concurrent.futures import ProcessPoolExecutor import os,time def func(i): print("Process",i,os.getpid()) time.sleep(0.1) print("Process %s end" % (i)) if __name__ == "__main__": p = ProcessPoolExecutor(5) p.submit(func,11) p.shutdown() print("主进程:",os.getpid())
例2:
from concurrent.futures import ProcessPoolExecutor import os,time def func(i): print("Process",i,os.getpid()) time.sleep(0.1) print("Process %s end" % (i)) return i * "*" # 回调函数 def call_back(args): print("call back:",os.getpid()) # print(args) print(args.result()) if __name__ == "__main__": # 同一时间最多允许5个进程并发 tp = ProcessPoolExecutor(5) for i in range(1,11): tp.submit(func,i).add_done_callback(call_back) tp.shutdown() print("主进程id:",os.getpid())