python 并发编程 同步调用和异步调用 回调函数
提交任务的两张方式:
1.同步调用
2.异步调用
同步调用:提交完任务后,就在原地等待任务执行完后,拿到结果,再执行下一行代码
同步调用,导致程序串行执行
from concurrent.futures import ThreadPoolExecutor import time import random def la(name): print("%s is 正在拉" % name) time.sleep(random.randint(1,3)) res = random.randint(1,10) * "#" return {"name":name,"res":res} def weigh(shit): name = shit["name"] size = len(shit["res"]) print("%s 拉了《%s》kg" %(name,size)) if __name__ == "__main__": pool = ThreadPoolExecutor(13) shit1 = pool.submit(la,"mike").result() weigh(shit1) shit2 = pool.submit(la,"peter").result() weigh(shit2) shit3 = pool.submit(la,"jack").result() weigh(shit3) ''' mike is 正在拉 mike 拉了《2》kg peter is 正在拉 peter 拉了《9》kg jack is 正在拉 jack 拉了《4》kg '''
异步调用:提交完任务后,不再原地等待任务执行完
from concurrent.futures import ThreadPoolExecutor import time import random def la(name): print("%s is 正在拉" % name) time.sleep(random.randint(1,3)) res = random.randint(1,10) * "#" return weigh({"name":name,"res":res}) def weigh(shit): name = shit["name"] size = len(shit["res"]) print("%s 拉了《%s》kg" %(name,size)) if __name__ == "__main__": pool = ThreadPoolExecutor(13) pool.submit(la,"mike") pool.submit(la,"peter") pool.submit(la,"jack") ''' mike is 正在拉 peter is 正在拉 jack is 正在拉 mike 拉了《3》kg jack 拉了《8》kg peter 拉了《1》kg '''
回调函数
可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,并接收任务对象的返回值当作参数传给绑定的函数,该函数称为回调函数
add_done_callback()
传的是要绑定的函数,还要在函数,func拿到的是一个future对象obj,需要用obj.result()拿到结果
from concurrent.futures import ThreadPoolExecutor import time import random def la(name): print("%s is 正在拉" % name) time.sleep(random.randint(1,3)) res = random.randint(1,10) * "#" return {"name": name, "res": res} def weigh(shit): shit = shit.result() name = shit["name"] size = len(shit["res"]) print("%s 拉了《%s》kg" %(name,size)) if __name__ == "__main__": pool = ThreadPoolExecutor(13) pool.submit(la,"mike").add_done_callback(weigh) pool.submit(la,"peter").add_done_callback(weigh) pool.submit(la,"jack").add_done_callback(weigh)
同步调用就是阻塞?
同步和阻塞没有关系,同步调用只是一种提交任务方式,同步提交完任务后,不管程序是计算密集型还是io密集型程序,它都会原地等待任务执行。