go 通道 go語言通道channel

2021-08-08 19:25:06 字數 2464 閱讀 4048

通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。

通道,他有點像在兩個routine之間架設的管道,乙個goroutine可以往這個管道裡塞資料,另外乙個可以從這個管道裡取資料,有點類似於我們說的佇列。

宣告乙個通道很簡單,我們使用chan關鍵字即可,除此之外,還要指定通道中傳送和接收資料的型別,這樣我們才能知道,要傳送什麼型別的資料給通道,也知道從這個通道裡可以接收到什麼型別的資料。

ch:=make(chan

int)

通道型別和map這些型別一樣,可以使用內建的make函式宣告初始化,這裡我們初始化了乙個chan int型別的通道,所以我們只能往這個通道裡傳送int型別的資料,當然接收也只能是int型別的資料。

我們知道,通道是用於在goroutine之間通訊的,它具有傳送和接收兩個操作,而且這兩個操作的運算子都是<-。

ch <- 2

//傳送數值2給這個通道

x:=<-ch //從通道裡讀取值,並把讀取的值賦值給x變數

<-ch //從通道裡讀取值,然後忽略

看例子,慢慢理解傳送和接收的用法。傳送操作<-在通道的後面,看箭頭方向,表示把數值2傳送到通道ch裡;接收操作<-在通道的前面,而且是乙個一元操作符,看箭頭方向,表示從通道ch裡讀取資料。讀取的資料可以賦值給乙個變數,也可以忽略。

通道我們還可以使用內建的close函式關閉。

close

(ch)

如果乙個通道被關閉了,我們就不能往這個通道裡傳送資料了,如果傳送的話,會引起painc異常。但是,我們還可以接收通道裡的資料,如果通道裡沒有資料的話,接收的資料是nil。

剛剛我們使用make函式初始化的時候,只有乙個引數,其實make還可以有第二個引數,用於指定通道的大小。預設沒有第二個引數的時候,通道的大小為0,這種通道也被成為無緩衝通道。

ch:=make(chan

int)

ch:=make(chan

int,0)

ch:=make(chan

int,2)

看例子,其中第乙個和第二個初始化是等價的。第三個初始化建立了乙個大小為2的通道,這種稱為有緩衝通道。

無緩衝的通道

無緩衝的通道指的是通道的大小為0,也就是說,這種型別的通道在接收前沒有能力儲存任何值,它要求傳送goroutine和接收goroutine同時準備好,才可以完成傳送和接收操作。

從上面無緩衝的通道定義來看,傳送goroutine和接收gouroutine必須是同步的,同時準備後,如果沒有同時準備好的話,先執行的操作就會阻塞等待,直到另乙個相對應的操作準備好為止。這種無緩衝的通道我們也稱之為同步通道。

func main() 

ch <- sum

}()fmt.println(<-ch)

}

在前面的例子中,我們為了演示goroutine,防止程式提前終止,都是使用sync.waitgroup進行等待,現在的這個例子就不用了,我們使用同步通道來等待。

在計算sum和的goroutine沒有執行完,把值賦給ch通道之前,fmt.println(<-ch)會一直等待,所以main主goroutine就不會終止,只有當計算和的goroutine完成後,並且傳送到ch通道的操作準備好後,同時<-ch就會接收計算好的值,然後列印出來。

例子:

package main

import (

"fmt"

"sync"

)var wg sync.waitgroup

func printer(ch chan

int)

wg.done()

}// main is the entry point for the program.

func main()

close(c)

wg.wait()

}

單向通道:

有時候,我們有一些特殊場景,比如限制乙個通道只可以接收,但是不能傳送;有時候限制乙個通道只能傳送,但是不能接收,這種通道我們稱為單向通道。

定義單向通道也很簡單,只需要在定義的時候,帶上<-即可。

var send chan

<- int

//只能傳送

var receive <-chan

int//只能接收

注意<-操作符的為止,在後面是只能傳送,對應傳送操作;在前面是只能接收,對應接收操作。

單向通道應用於函式或者方法的引數比較多,比如

func counter(out chan

<- int)

例子這樣的,只能進行傳送操作,防止誤操作,使用了接收操作,如果使用了接收操作,在編譯的時候就會報錯的。

go語言通道插入0 Go 語言通道

51reboot 運維開發 golang 課程 k8s 課程 python 自動化高階課程 python 基礎實戰課程 運維前端課程 課程試聽預約請掃碼 原子函式和互斥函式都能工作,但是依靠它們都不會讓編寫併發程式變得更簡單,更不容易出錯,或者更有趣。在 go 語言裡,你可以使用通道來傳送和接收需要...

go語言通道插入0 Go語言之通道

所以在多個goroutine併發中,我們不僅可以通過原子函式和互斥鎖保證對共享資源的安全訪問,消除競爭的狀態,還可以通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。通道,它有點像在兩個routine之間架設的管道 乙個goroutine可以往這個管道裡塞資料,另外乙個...

Go語言 通道型別

通道 channel 是go語言中一種非常獨特的資料結構。它可用於在不同goroutine之間傳遞型別化的資料,並且是併發安全的。相比之下,我們之前介紹的那些資料型別都不是併發安全的。這一點需要特別注意。goroutine 也稱為go程式 可以被看做是承載可被併發執行的 塊的載體。它們由go語言的執...