go通道關閉
只有在當需要告訴接收者,我(傳送者)不會再提供新的值的時候,才需要關閉通道。
只有傳送者需要關閉通道,接收者永遠不會需要。
問題1:如何關閉通道
通過執行close(ch)來關閉一個通道,這個操作會將通道標記為無法通過<- 接受更多的值。
給已經關閉的通道傳送或者再次關閉都會導致執行時的 panic。在建立一個通道後使用 defer 語句是個不錯的辦法。
問題2:如何檢測通道是不是關閉了(或阻塞了)
如果v收到值了,則ok的值是true。
根據ok的值,我們就能知道通道要麼是關閉了,要麼是阻塞了。
實現非阻塞通道的讀取,需要使用 select。
使用 for-range 語句
for在迴圈遍歷時,一旦結束,就退出。
記錄執行時間和效能測試可以幫助你找到最小的快取容量帶來最好的效能。
通訊開關:select語句
它的行為像是 “你準備好了嗎” 的輪詢機制;select
監聽進入通道的資料。
在任何一個 case 中執行break
或者return
,select 就結束了。
注意:一個select語句只監聽一次,監聽到值後,就開始執行後面的語句。因此要用for來迴圈。
後臺服務模式
每秒處理的頻率可以根據機器負載(和 / 或)資源的情況而增加或減少。
滴答器:按一定頻率滴答。
定時器:只發送一次。
簡單超時模式
另一種超時:
有多個case
符合條件時,select
對case
的選擇是偽隨機的。
一個用到recover
的程式停掉了伺服器內部一個失敗的協程而不影響其他協程的工作。
使用通道進行同步:使用一個通道接受需要處理的任務,一個通道接受處理完成的任務(及其結果)
對一個通道讀資料和寫資料的整個過程是原子性的。
使用鎖的情景:
訪問共享資料結構中的快取資訊
儲存應用程式上下文和狀態資訊資料
使用通道的情景:
與非同步操作的結果進行互動
分發任務
傳遞資料所有權
生成器
惰性求值
但是得小心,使用大量的 go 協程的開銷可能會超過帶來的效能增益
通過巧妙地使用空介面、閉包和高階函式,我們能實現一個通用的惰性生產器的工廠函式BuildLazyEvaluator
(這個應該放在一個工具包中實現)。
需要抽象的能力,不然看這種程式碼會頭疼,這種程式碼不如過程式程式碼一目瞭然,需要轉大彎。
但這種程式碼能減小我們的程式碼檔案,所以還是得硬著頭皮看。
協程和通道在client-server型別的應用上大有用處
客戶端請求本身包含了一個頻道(channel),服務端可以用它來發送響應。