首頁 > 軟體

Go語言中的通道channel詳情

2022-02-25 19:00:37

一、Go語言通道基礎概念

1.channel產生背景

    執行緒之間進行通訊的時候,會因為資源的爭奪而產生竟態問題,為了保證資料交換的正確性,必須使用互斥量給記憶體進行加鎖,go語言並行的模型是CSP,提倡通過通訊共用記憶體,而不是通過共用記憶體而實現通訊,通道恰巧滿足這種需求。

2.channel工作方式

    channel類似與一個佇列,滿足先進先出的規則,嚴格保證收發資料的順序,每一個通道只能通 過固定型別的資料如果通道進行大型結構體、字串的傳輸,可以將對應的指標傳進去,儘量的節省空間

二、通道使用語法

1.通道的宣告與初始化

    //定義一個通道物件使用,其中int可以換為自己需要的型別
    var a chan int  
    //初始化只有一個位置的通道(第一個引數代表通道型別,第二個引數代表通道有幾個位置)
    //位置存滿後新的資料將存不進來(阻塞)
    a = make(chan int,1)

2.將資料放入通道內

  • 取出資料使用操作符 <-操作符右是輸入變數,操作符左是通道代表資料流入通道內

程式碼如下:

   // 宣告一個通道
    var a chan int
        a <- 5

3.從通道內取出資料

  •  取出資料也使用操作符 <-操作符右是通道,操作符左是接受變數

程式碼如下:

  //宣告一個通道型別
    var a chan int
    fmt.Println("未初始化的通道", a)
    a = make(chan int)
    // wg.Add(1)
    go func(a chan int) {
        // defer wg.Done()
        for {
            x := <-a
            fmt.Println("接收到了資料:", x)
        }
    }(a)

4.關閉通道close

    如果通道重複關閉或者關閉一個沒有初始化的通道就會丟擲錯誤

 close(a)//a為待關閉的通道

在並行函數中一次關閉通道程式碼如下:

// 互斥鎖物件
var once sync.Once
//並行函數
//這個函數的目的是將a通道內資料乘以10傳送到通道b內
func f2(a <-chan int, b chan<- int) {
    defer wg.Done()
    for {
        x, ok := <-a
        if !ok {
            break
        }
        fmt.Println(x)
        b <- x * 10
    }
    // 確保b通道只關閉一次
    once.Do(func() {
        close(b)
    })
}

三、單項通道及通道的狀態分析

1.單項輸出通道

    var b <-chan int

2.單項輸入通道

    var b chan<- int

範例函數:

//單項通道一般做函數引數,作為一種規範防止通道混用
//此函數完成的功能是將a內的資料乘以10放入通道b內
func f2(a <-chan int, b chan<- int) {
    for {
        x, ok := <-a
        if !ok {
            break
        }
        fmt.Println(x)
        b <- x * 10
    }
}

3.通道的狀態

channelnil未初始化空通道滿通道非空
接收阻塞阻塞接收值接收值
傳送阻塞傳送值阻塞傳送值
關閉panic關閉成功關閉成功關閉成功
關閉後返回的資料panic返回0值資料讀完後返回零值資料讀完返回零值

四、通道死鎖原因分析

注意以下情況:

在使用通道的時候,從以上表格可知有時會進入阻塞狀態,結合waitGroup,如果在主函數等待使用通道的函數執行結束,而使用通道的函數並且通道陷入阻塞狀態,如果有其他函數對其進行喚醒則不會死鎖,如果沒有其他函數可以對其進行喚醒則會丟擲死鎖異常。

總結:
通道將資料隔離在每一份通道內,在並行的情況下可以很好的使用資料,當然要熟悉通道阻塞的幾種情況,避免死鎖異常。

到此這篇關於Go語言中的通道channel詳情的文章就介紹到這了,更多相關Go語言中的通道channel內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com