go語音之進階篇 channel介紹
阿新 • • 發佈:2019-01-16
傳遞 int 讀寫 字符 進階 非阻塞 pac 元素 個人
1、channel介紹
和map類似,channel也一個對應make創建的底層數據結構的引用。
當我們復制一個channel或用於函數參數傳遞時,我們只是拷貝了一個channel引用,因此調用者何被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。
定義一個channel時,也需要定義發送到channel的值的類型。channel可以使用內置的make()函數來創建:
make(chan Type) //等價於make(chan Type, 0) make(chan Type, capacity)
當 capacity= 0 時,channel 是無緩沖阻塞讀寫的,當capacity> 0 時,channel 有緩沖、是非阻塞的,直到寫滿 capacity個元素才阻塞寫入。
channel通過操作符<-來接收和發送數據,發送和接收數據語法:
channel <- value //發送value到channel <-channel //接收並將其丟棄 x := <-channel //從channel中接收數據,並賦值給x x, ok := <-channel //功能同上,同時檢查通道是否已關閉或者是否為空
默認情況下,channel接收和發送數據都是阻塞的,除非另一端已經準備好,這樣就使得goroutine同步變的更加的簡單,而不需要顯式的lock。
示例:
package main import ( "fmt" "time" ) //全局變量,創建一個channel var ch = make(chan int) //定義一個打印機,參數為字符串,按每個字符打印 //打印機屬於公共資源 func Printer(str string) { for _, data := range str { fmt.Printf("%c", data) time.Sleep(time.Second) } fmt.Printf("\n") } //person1執行完後,才能到person2執行 func person1() { Printer("hello") ch <- 666 //給管道寫數據,發送 } func person2() { <-ch //從管道取數據,接收,如果通道沒有數據他就會阻塞 Printer("world") } func main() { //新建2個協程,代表2個人,2個人同時使用打印機 go person1() go person2() //特地不讓主協程結束,死循環 for { } }
執行結果:
hello world
go語音之進階篇 channel介紹