提交任務的兩張方式:
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密集型程序,它都會原地等待任務執行。