(十)非同步呼叫與回撥機制
阿新 • • 發佈:2020-07-29
一、同步呼叫
提交任務有兩種方式:同步呼叫,非同步呼叫。
同步呼叫:提交完任務後,就在原地等待任務執行完畢,拿到結果再執行下一行程式碼,導致程式是序列執行。
例子:今年你們公司開年會,舉辦了一個吃漢堡大賽,然後把計算下大家一共吃了多少個,誰的最多,誰發的年終獎就最多。
# 1,同步呼叫:提交完任務後,就在原地等待任務執行完畢,拿到結果再執行下一行程式碼,導致程式是序列執行。 from concurrent.futures import ThreadPoolExecutor import time,random def eat(name): print("%s 正在吃。" % name) time.sleep(random.randint(3,5)) # 吃的時間 res = random.randint(7,13) # 吃了幾個 return {"name":name,"res":res} def count(hamburger): name = hamburger["name"] num = hamburger["res"] print("%s 吃了《%s》個。" % (name,num)) if __name__ == '__main__': pool = ThreadPoolExecutor(3) # 參賽人數,用執行緒池 shit1= pool.submit(eat,"託兒所").result() # 提交任務,等待任務執行完畢,拿到結果 count(shit1) shit2 = pool.submit(eat,"兒童劫").result() count(shit2) shit3 = pool.submit(eat,"瑞萌萌").result() count(shit3) """ 託兒所 正在吃。 託兒所 吃了《8》個。 兒童劫 正在吃。 兒童劫 吃了《12》個。 瑞萌萌 正在吃。 瑞萌萌 吃了《8》個。 """
二、非同步呼叫與回撥函式
非同步呼叫:提交完任務後,不在原地等待任務執行完畢。
回撥函式:可以為程序池或執行緒池內的每個程序或執行緒繫結一個函式,該函式在程序或執行緒的任務執行完畢後自動觸發,並接收任務的返回值當作引數,該函式稱為回撥函式。
# 2,非同步呼叫:提交完任務後,不在原地等待任務執行完畢, from concurrent.futures import ThreadPoolExecutor import time,random def eat(name): print("%s 正在吃。" % name) time.sleep(random.randint(3,5)) # 吃的時間 res = random.randint(7,13) # 吃幾個 return {"name":name,"res":res} # weight({"name":name,"res":res}) # 這樣寫的話,相當於把兩個函式寫到一起了,耦合了,而我們是要解耦合的 def count(hamburger): hamburger = hamburger.result() # 這裡的hamburger拿到的是一個物件 name = hamburger["name"] num = hamburger["res"] print("%s 吃了《%s》個." % (name,num)) if __name__ == '__main__': pool = ThreadPoolExecutor(3) # 參賽人數,用執行緒池 # 回撥函式是在,前面的函式執行完,有返回值了,自動觸發這個功能,把前面的物件直接當引數傳給weight pool.submit(eat,"託兒所").add_done_callback(count) # 前面是物件,後面的是回撥函式 pool.submit(eat,"兒童劫").add_done_callback(count) pool.submit(eat,"瑞萌萌").add_done_callback(count) # count拿到的是一個future物件obj,需要用obj.result()拿到結果,也就是 hamburger.result() """ 託兒所 正在吃。 兒童劫 正在吃。 瑞萌萌 正在吃。 瑞萌萌 吃了《12》個. 託兒所 吃了《12》個. 兒童劫 吃了《11》個. """