1. 程式人生 > >同步呼叫 非同步呼叫+回撥機制

同步呼叫 非同步呼叫+回撥機制


1 同步呼叫 非同步呼叫+回撥機制
提交任務的兩種方式:
同步呼叫 :提交任務必須等待任務完成,才能執行下一行
非同步呼叫 :提交任務不需要等待任務完成,立即執行下一行
任務執行的三種狀態:
阻塞
阻塞 遇到了IO操作 程式碼卡主 無法執行下一行 CPU會切換到其他任務
非阻塞:
就緒
執行

非同步回撥 ******
什麼是非同步回撥?
在發起非同步任務後 子執行緒或子程序 完成任務後需要通知任務發起方
如何通知 就呼叫一個函式
為什麼需要回調?
由於任務是非同步執行 任務發起方不知道啊什麼時候完成
所以使用回撥的方式告訴發起方任務執行結果 其他方式也可以將資料交還給主程序
1.shutdown 主程序會等到所有任務完成
2.result函式 會阻塞直到任務完成
都會阻塞 導致效率降低 所以使用回撥
注意點:
回撥函式什麼時候被執行? 子程序任務完成時
誰在執行回撥函式? 主程序
執行緒的非同步回撥:
使用方式都相同 唯一的不同是執行回撥函式 是子執行緒在執行

2.執行緒佇列 ***
佇列
堆疊
優先順序佇列

3、單執行緒下實現併發(***)
什麼是協程:
單執行緒下實現併發,在應用程式級別實現多個任務之間切換+儲存狀態
併發:看起來是同時執行
併發實現的本質=切換+儲存狀態
切換:
1、遇到IO阻塞會切換(可以提升執行效率)
2、佔用cpu時間過長或者有一個優先順序更高的任務搶走了cpu

為什麼需要協程
因為GIL的存在 同一時間只有一個執行緒在執行 如果只有單核沒有問題
但是無法利用多核資源 只有儘可能提升單執行緒的效率
主線和子線切換是隨機的

協程的實現
1 yield 把函式做成了生成器 生成器會自動儲存狀態
2 greenlet 幫我們封裝yield 可以實現任務切換
建立物件時 制定任務就是函式 在函式中手動來switch切換任務
3 gevent 在greenlet的基礎上封裝了檢測IO


協程的應用場景:
(沒有IO絕對不使用協程) TCP 多客戶端實現方式

總結點:
單線下實現併發 將io阻塞時間用於執行計算 可以提高效率 原理:一直使用CPU直到超時