1. 程式人生 > >csp 併發模型

csp 併發模型

channel:

channel一種個安全的雙端佇列,任何任務只要持有channel的引用,就可以向一端加入訊息,也可以向一端刪除訊息,訊息的消費者和生產者不清楚對方是誰。

channel分為無緩衝和有緩衝,無緩衝會同步阻塞,即每次生產訊息都會阻塞到消費者將訊息消費;有緩衝的不會立刻阻塞。

關閉channel:向關閉的channel讀資料會是nil,向關閉的channel寫資料會被棄用。

channel緩衝區已滿的處理策略:

  1. 預設策略是阻塞寫訊息,直至寫成功
  2. dropping-buffer:緩衝滿後忽略最遲的訊息
  3. sliding-buffer:緩衝滿後棄用最早的訊息
  4. 為什麼不支援容量自動擴充套件的channel:有限的資源總有會遇到資源耗盡的時候,如果因為各種外來內在原因而出現訊息堆積的場景,在重重程式碼種會變成非常難排除的bug,所以最好的處理方案,就是在任何場景使用緩衝的channel,必須考慮緩衝溢位如何處理

go 塊

執行緒在其他語言比如Java的使用方案,首先可以單獨建立執行緒處理任務,因為執行緒重複建立銷燬會帶來很多的效能開銷,所以首選使用執行緒池技術,但是執行緒池技術線上程通訊的時候,還有其他缺陷比如,如果執行緒被阻塞,這個執行緒將被無限期佔用,這個在高併發的場景下,削弱了執行緒池的優勢。
如果要補全這個缺陷,也有其他的解決方案比如事件驅動,僅僅當被通知IO準備好時,執行緒才會去處理這個IO請求,這個方案可以實現但是會限制程式碼的編寫風格,使用複雜,可讀性非常差。
go塊從根本提供瞭解決方案,在底層通訊程式碼中,將底層序列通訊的程式碼重寫為事件驅動的程式碼(channel?),而上層業務程式碼無需考慮IO切換,就能實現靈活的執行緒阻塞時的切換。
控制反轉

:go塊程式碼是一個狀態機,當讀寫channel時,會將go塊狀態變為暫停,主動讓出執行緒,等待go塊繼續執行的時候,會請求已有或新執行緒,然後狀態轉換後繼續執行。
意義:不用擔心資源而隨意建立併發任務。