1. 程式人生 > 實用技巧 >go:goroutine與channel

go:goroutine與channel

goroutine:可以理解為一個輕量的執行緒,語法:go 函式名()

channel:中文為“通道”,可以理解為一個管,一端進行接資料,另一端收資料。語法:c:=make(chan int)。通道需要有接收和傳送。

關於goroutine與channel的組合使用,見如下2個例子。

例1:channel通訊

 1 func sum(a int,c chan int){
 2     num:=a+100
 3     c <- num
 4 }
 5 
 6 func main(){
 7     c:=make(chan int)
 8     go sum(100
,c) 9 sum1:= <- c 10 fmt.Println(sum) 11 }

輸出:>>>200

備註:

a.這段程式碼寫了2個函式,sum()與main()通過channel通訊,並且在main中使用goroutine開啟一個執行緒。

b.sum()函式的引數有一個int和一個channel,且在第3行將函式的執行結果使用channel接收。在mian()函式中,channel的資料傳送給變數sum1,以此實現channel通訊的作用。

c.在第8行,通過go開始了一個協程,如果去掉go就相當於沒有開啟協程,會出現dead lock。或者修改第7行第8行如下:

...
c:=make(chan int,1)
sum1(100,c)
...

修改後的c在make時就定義了一個緩衝區,緩衝區的大小為1,緩衝區可以理解為佇列長度。執行時超出佇列長度也會報錯。

例2:channel的通知作用

 1 var complete chan int =make(chan int)
 2 
 3 func loop(){
 4     for i:=0;i<10;i++{
 5         fmt.Printf("%d \t",i)
 6     }
 7     complete <- 0
 8 }
 9 
10 func main(){
11     go loop()
12 // loop() 13 <- complete

結果:>>>0 1 2 3 4 5 6 7 8 9

備註:

a.這段程式碼主要是描述channel的通知作用:main函式的 <- complete 其實就是阻塞住main線不讓main線過早跑完,直到main線從complete中讀出訊息(0)

b.第11行和第12行,loop()被呼叫2次,第一次是roroutine開啟的執行緒,第二次是main()開啟的。而main()退出比較快,它執行完了goroutine還未來得及執行。或者可以在12行後加一個延遲(time.Sleep(time.Second)),加了之後兩個執行緒都可以執行、

c.第7行體現了channel的通知作用:當loop()函式體執行完畢後,會發訊息給channel,訊息是0;在第13行,如果取到了訊息(0)則說明goroutine的執行緒跑完了,否則mian()會阻塞住。

本文轉載自:https://blog.csdn.net/HYZX_9987/article/details/97528721?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param