go中的Channel (總結於尚矽谷go)

2021-10-19 22:54:21 字數 3294 閱讀 6486

​ channel是乙個資料型別,主要用來解決協程的同步問題以及協程之間資料共享(資料傳遞)的問題。可以把它看成管道,一端讀,一端寫

goroutine執行在相同的位址空間,因此訪問共享記憶體必須做好同步 goroutine 奉行通過通訊來共享記憶體,而不是共享記憶體來通訊。引⽤型別 channel可用於多個 goroutine 通訊。其內部實現了同步,確保併發安全。

定義channel的變數方式

make(chan type)  //等價於make(chan type, 0)

make(chan type, capacity)

channel的操作方式
channel 

預設情況下,channel接收和傳送資料都是阻塞的,除非另一端已經準備好,這樣就使得goroutine同步變的更加的簡單,而不需要顯式的lock

c :=

make

(chan

int)

gofunc()

()num :=

fmt.

println

("num = "

, num)

fmt.

println

("main協程結束"

)

無緩衝區channel:

​ 不會儲存接受到的值

ch :=

make

(chan

int)

gofunc()

}()for i:=

0;i<

5;i++

}

有緩衝區channel:

會儲存接受到的值

ch :=

make

(chan

int,5)

//存滿5元素之前不會堵塞

fmt.

println

(len

(ch)

) fmt.

println

(cap

(ch))go

func()

}() time.

sleep

(time.second *5)

for i:=

0;i<

8;i++

input//

sub go

:len:1

cap:

5sub go

:len:2

cap:

5sub go

:len:3

cap:

5sub go

:len:4

cap:

5sub go

:len:5

cap:

5main go:0

main go:1

main go:2

main go:3

main go:4

main go:5

sub go

:len:5

cap:

5// 輸出的多了 是因為io操作的延遲所導致的

sub go

:len:0

cap:

5sub go

:len:1

cap:

5sub go

:len:2

cap:

5sub go

:len:3

cap:

5main go:6

main go

:7

關閉channel

如果傳送者知道,沒有更多的值需要傳送到channel的話,那麼讓接收者也能及時知道沒有多餘的值可接收將是有用的,因為接收者可以停止不必要的接收等待。這可以通過內建的close函式來關閉channel實現。

ch :=

make

(chan

int)

gofunc()

close

(ch)}(

)for

else

}

l 關閉channel後,無法向channel 再傳送資料(引發 panic 錯誤後導致接收立即返回零值);

l 關閉channel後,可以繼續從channel接收資料;

可以使用range來迭代不斷操作channel

c :=

make

(chan

int)

gofunc()

//把 close(c) 注釋掉,程式會一直阻塞在 for data := range c 那一行

close

(c)}()

for data :=

range c

fmt.

println

("finished"

)

單向channel

預設情況下,通道channel是雙向的,也就是,既可以往裡面傳送資料也可以同裡面接收資料。

但是,我們經常見乙個通道作為引數進行傳遞而值希望對方是單向使用的,要麼只讓它傳送資料,要麼只讓它接收資料,這時候我們可以指定通道的方向。

宣告方式:

var ch1 chan int

// ch1是乙個正常的channel,是雙向的

var ch2 chan<

- float64 // ch2是單向channel,只用於寫float64資料

var ch3 <

-chan int

// ch3是單向channel,只用於讀int資料

chan<

-//表示資料進入管道,要把資料寫進管道,對於呼叫者就是輸出。

<

-chan //表示資料從管道出來,對於呼叫者就是得到管道的資料,當然就是輸入。

可以將 channel 隱式轉換為單向佇列,只收或只發,不能將單向 channel 轉換為普通 channel

ch :=

make

(chan

int)

var writech chan

int= ch

writech

123var readch

chan

int= ch

num :=

fmt.

println

(num)

go中channel簡單使用

channel是go語言在語言級別提供的goroutine間的通訊機制。我們可以使用channel在兩個或者多個goroutine之間傳遞資訊。channel是程序內的通訊。channel分為帶緩衝的以及不帶緩衝的。ch make chan int 建立乙個不帶緩衝的channel。ch make ...

Go語言裡channel的死鎖

最近看了下go語言並寫了些示例 在用到channel的時候報了個奇怪的錯誤然後退出 fatal error all goroutines are asleep deadlock 在stackoverflow上搜到 查了查,出錯的 如下 func chanfunc c chan int,d chan ...

Go語言的管道Channel用法

channel 是有型別的管道,可以用 channel 操作符 ch v 箭頭 就是資料流的方向。和 map 與 slice 一樣,channel 使用前必須建立 ch make chan int 預設情況下,在另一端準備好之前,傳送和接收都會阻塞。這使得 goroutine 可以在沒有明確的鎖或競...