讀取通道操作:
val,ok := <-ch
使用斷言讀取通道中的值,檢查通道是否還有內容,以及判斷通道是否已經關閉,當通道中沒有信息,且通道已經關閉時,ok值為false,當通道沒有關閉,但是通道中沒有信息,程序將會阻塞,如果通道中有內容,則ok值是true。
另一種不使用斷言的方式讀取通道
val := <-ch
寫入與讀取通道
讀取不帶緩沖的通道示例方法:
package mainimport ( "fmt")func main() { // 定義一個不帶緩沖的通道,通道中數據類型是int var c = make(chan int) // 開啟一個攜程,讀取通道中的內容 go func() { fmt.Println("寫入信息是:", <-c) }() // 向通道中寫入數據 c <- 1}
輸出結果:
寫入信息是: 1
當對帶緩沖的通道進行讀寫時,只要通道中數據長度不大于緩沖長度,就不會出現阻塞,但是讀取帶緩沖的通道,通道中沒有內容時,程序依然會進入阻塞狀態。所以,帶緩沖的通道,只對寫入產生影響。下邊來一個示例:
package mainimport ( "fmt")func main() { var c = make(chan int, 3) c <- 1 c <- 2 c <- 3 //c <- 4 fmt.Println("end") }
輸出信息是:
end
當向帶3個緩沖的通道中寫入內容時,由于只寫入了3次,通道的長度剛好等于緩沖的長度,程序沒有阻塞,當將 c <- 4 前邊的注釋去掉后,由于沒有程序去讀取這個通道,主程序進入死鎖狀態而導致異常。
協程通信
通道類型變量的實質上是一個地址,如下邊示例代碼:
package mainimport ( "fmt")func main() { var c = make(chan int, 3) fmt.Println(c) }
輸出結果:
0xc042072080
所以,當通道類型變量當做參數傳入函數后,在函數中可以直接對通道中的值進行修改。雖然chan類型變量是一個地址,但是golang不允許使用取值操作符( * )來操作chan類型變量。但是如果你先對chan類型變量使用取地址操作符(&),然后再使用取值操作符(*),這種操作方法還是可以正常運行的,但是這意義不大,除非你的目的是在函數調用中,重新定義一個chan類型變量替換原來的變量。
chan的這些特性,可以很好的實現協程之間的同步功能。不帶緩沖的通道,是一種零容忍的等待,可以實現強制同步;帶緩沖的通道,是有一定量容忍度的等待,可以實現允許有一定時間差的同步。
簡單的協程間通信例子:
package mainimport ( "fmt" "time")func main() { var c = make(chan int) go func() { fmt.Println("待命模式:") // 讀取通道時產生阻塞,等待其他協程向通道寫入信息 fmt.Println("命令代碼是:", <-c) }() go func() { // 延時3秒,向通道中寫入信息 time.Sleep(time.Second * 3) fmt.Println("發送命令:") c <- 8 close(c) }() time.Sleep(time.Second * 5) fmt.Println("執行完成") }
輸出信息是:
待命模式: 發送命令: 命令代碼是: 8 執行完成
相關推薦:
HTML validate HTML驗證_HTML/Xhtml_網頁制作
HTML技巧匯編_CSS/HTML
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com