1. 程式人生 > 其它 >39. channel管道 | 厚土Go學習筆記

39. channel管道 | 厚土Go學習筆記

channel 是有型別的管道,channel 的操作符是 <- ,可以用來發送或接收值。
ch <- v    //賦值給管道,管道接收值
v := <- ch    //管道傳送值

管道的使用也是必須建立的。建立的方式是

ch := make(chan int)

管道預設情況下,在另一端準備好之前,傳送和接收都會堵塞。這使得 goroutine 可以在沒有明確的鎖的情況下進行同步。

看一個完整的例子

package main

import "fmt"

func sum(a []int, c chan int)  {
    sum := 0
    for _, v := range a{
        sum += v
    }
    c <- sum
}
func main() {
    a := []int{2, 0, 1, 7, 0, 8, 2, 7, 1, 7, 4}
    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c
    fmt.Println(x, y, x + y)
}

執行結果

29 10 39

channel 是可以設定緩衝的,向有緩衝的 channel 傳送資料的時候,在緩衝區滿的時候才會阻塞。而當緩衝區為空的時候,接收操作會阻塞。

設定 channel 緩衝通道數量的方式如下

ch := make(chan int, 100)

這個通道數量是100。

展示一個有緩衝區的例子

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 100
    ch <- 5
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

執行結果是

100
5

本例設定了緩衝數為 2。意思是在一個 goroutine 裡可以有兩個傳值操作,在通道值被接收前通道會被佔滿。如果有第三個值傳入通道會發生失敗。

ch <- 100
ch <- 5
ch <- 77

增加一個傳入值,再執行看看,會得到如下結果

fatal error: all goroutines are asleep - deadlock!